Angular 深入淺出三十天:表單與測試 Day22 - 把 Cypress 變成 TypeScript 版

Day22

平常都用慣 TypeScript 版的 Cypress,但這兩天都用 JavaScript 在寫測試,令我有點不太習慣。

雖然 JS 版或 TS 版的差別並沒有多大,但少了一些開發時期的型別檢查與 Intellisense 還是令人感到彆扭。

因此,我們今天就來分享如何把 JS 版的 Cypress 變成 TS 版吧!

Angular 專案

首先,如果你的專案是 Angular ,預設不會配有任何 E2E 自動化測試工具,如果我們想要在 Angular 的專案使用 Cypress ,可以直接在終端機輸入以下指令:

1
$ ng add @cypress/schematic

等待它執行完成後,你會發現 Angular Schematics 除了幫你裝好 Cypress 之後,也在 package.json 裡的 scripts 區段增加了以下三個指令:

1
2
3
4
5
6
7
{
"scripts": {
"e2e": "ng e2e",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
}
}

並且在 angular.json 裡的 architect 區段添加了以下設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"cypress-run": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "ng-with-cypress:serve"
},
"configurations": {
"production": {
"devServerTarget": "ng-with-cypress:serve:production"
}
}
},
"cypress-open": {
"builder": "@cypress/schematic:cypress",
"options": {
"watch": true,
"headless": false
}
},
"e2e": {
"builder": "@cypress/schematic:cypress",
"options": {
"devServerTarget": "ng-with-cypress:serve",
"watch": true,
"headless": false
},
"configurations": {
"production": {
"devServerTarget": "ng-with-cypress:serve:production"
}
}
}
}

e2e 的部份如果原本是使用 Protractor ,也會被調整過來。

這段設定的用意是讓 Angular CLI 知道,當我們要執行 cypress runcypress open 或是 ng e2e 的指令時,會連帶啟動 Angular 的服務,方便開發者使用時,不需額外自己啟動。

葛來芬多 Cypress 加 10 分!

此外,不可少的 cypress.json/cypress 資料夾當然也已經新增好了,而且 cypress.json 裡還已經幫我們配置了以下設定:

1
2
3
4
5
6
7
8
9
{
"integrationFolder": "cypress/integration",
"supportFile": "cypress/support/index.ts",
"videosFolder": "cypress/videos",
"screenshotsFolder": "cypress/screenshots",
"pluginsFile": "cypress/plugins/index.ts",
"fixturesFolder": "cypress/fixtures",
"baseUrl": "http://localhost:4200"
}

原本 /cypress 資料夾裡的 .js 檔也都變成了 .ts 檔,至此,我們就成功地把 Cypress 加入的 Angular 專案之中了,是不是超方便、超簡單的?!

Angular + Cypress 真的會把開發者寵壞

想知道什麼是 Angular Schematics 嗎?可以閱讀我的系列文:高效 Coding 術:Angular Schematics 實戰三十天

其他更多資訊,可以參考 Cypress 官方文件:https://docs.cypress.io/guides/migrating-to-cypress/protractor#Recommended-Installation

額外告訴大家一個小故事:其實這個 Schematics 原本不是官方維護的,這個 Schematics 的原身一開始是這個 @briebug/cypress-schematic ,不過後來被官方採用,才改由 Cypress 團隊維護。

衷心感謝所有曾經或正在為 Open Source 貢獻心力的每一個人。

其他類型專案

Angular 專案有 Angular Schematics ,但其他類型的專案或者是單單只有 Cypress 的專案怎辦?

別擔心,其實要做的事情也不會太繁瑣或困難。

首先,我們可以先在專案裡輸入以下指令以安裝 TypeScript :

1
$ npm install typescript --save-dev

or

1
$ yarn add typescript --dev

如果你的專案裡已經有安裝 TypeScript 的話請略過此步驟

然後在 /cypress 資料夾內新增一個 tsconfig.json 檔,並添加以下內容:

1
2
3
4
5
6
7
8
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
},
"include": ["**/*.ts"]
}

然後就可以把我們的 .js 檔都改成 .ts 檔,並把所有的 /// <reference types="cypress" /> 都拿掉囉!

不過如果你本來的專案就是 TypeScript 的,這時候你可能會發現你原本非 E2E 測試的 .spec.ts 檔案多了一堆紅色毛毛蟲:

VSCode Capture

然後你將滑鼠游標移到紅色毛毛蟲上, VSCode 會跟你說:

VSCode Capture

但是如果我們實際跑測試的話,又都會通過,那到底為什麼會有紅色毛毛蟲呢?

其實這是因為, VSCode 以為原本非 E2E 測試的 .spec.ts 是 Cypress 的檔案,所以它把原本是 Jasmineexpect()

VSCode Capture

誤認為是 Chaiexpect()

VSCode Capture

那該怎麼辦才好呢?

其實會造成這個狀況是因為 VSCode 它預設會吃 tsconfig.json 的設定,而如果原本根目錄就有 tsconfig.json ,然後又在 /cypress 裡加了 tsconfig.json 的話,就會出現這種狀況。

這時我們只需要在根目錄的 tsconfig.json 加上這個設定就可以恢復正常了:

1
2
3
4
5
6
7
8
9
{
"include": [
"src",
"node_modules/cypress"
],
"exclude": [
"node_modules/cypress"
]
}

如果這部份有遇到問題的話,可以參考我的 Source Code 的設定。

不過別高興地太早,還有一件事情需要我們留意與調整。

自訂 Command

之前在 JS 版本使用自訂 Command 時,自訂的 Command 沒有 Intellisense 很不方便,而且參數也都沒有辦法定義型別,也增加了後續維護的困難度。

而現在我們升級成 TS 版本後,想要享受 TS 所帶來的好處之前,我們需要在我們的 command.ts 檔的開頭增加以下程式碼:

1
2
3
4
5
6
7
declare namespace Cypress {
interface Chainable {
// 這裡面擺放的是自訂 Command 的宣告
// 例如:
fillWith(account: string, password: string): Chainable<string>
}
}

原本的自訂 Command 的區塊也可以一併調整成這樣:

1
2
3
4
Cypress.Commands.add('fillWith', (account: string, password: string) => {
cy.get('#account').type(account);
cy.get('#password').type(password);
})

如此一來,我們在寫測試案例的時候即可享有 Intellisense 與型別檢查的好處囉!

想知道更多可以參考官方的 TypeScript Support 文件

本日小結

今天的重點主要是升級完成後,千萬記得要在 command.ts 加上 namespace 的宣告,這點可能會是很多人會不小心忘記的地方。

此外,也記得將 /// <reference types="cypress" /> 從程式碼中移除,這個語法主要是針對 JS 的,升級 TS 之後有它反而會錯。

我今天的實作程式碼會放在 Github - Branch: day22 上供大家參考,不過雖然該專案是 Angular 專案,但我是使用「其他專案」的方式,所以在測試時會需要自己啟動 Angular 的服務。

同時也建議大家在看我的實作之前,先按照需求規格自己做一遍,之後再跟我的對照,看看自己的實作跟我的實作不同的地方在哪裡、有什麼好處與壞處,如此反覆咀嚼消化後,我相信你一定可以進步地非常快!

如果你有任何的問題或是回饋,還請麻煩留言給我讓我知道!

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×