Protractor 的 getText() 回傳型別到底是什麼?
使用了 TypeScript 之後,對於型別就非常敏感,都會要求自己要將傳入參數的型別與回傳型別明確指定,但 Protractor 在 page object 常用的 getText(),到底回傳型別是什麼呢?
Version
Angular CLI 1.1.2
Angular 4.2.3
Protractor 5.1.2
Symptoms
e2e/app.po.ts
1 | import { browser, by, element } from 'protractor'; |
在 Angular CLI 專案預設的 Protractor 範例,其 page object 的 nagivateTo() 與 getParagraphText() 並沒有加上回傳型別,既然使用了 TypeScript,就希望能盡量加上型別,由編譯器替我們檢查與保護。

有 get() 我們得知其回傳型別為 wdpromise.Promise<any>。

但實際替回傳型別加上 wdpromise.Promise<any> 之後,language service 會抱怨找不到 wdpromise namespace。

getText() 則完全沒提供任何回傳型別資訊,則 getParagraphText() 該回傳什麼型別呢?

實際執行 ng e2e,結果當然也是編譯失敗。
Recipes
由於 getText() 之後可以用 then(),在觀念上知道 getText() 回傳的是 Promise。

實際加上回傳型別 Promise<string>,language service 抱怨 promise.Promise<string> 與 Promise<string> 不相容,試試看回傳 promise.Promise<string> 看看。

改成回傳 promise.Promise<string> 之後,另外加上 import { promise } from 'selenium-webdriver'; 之後,language service 就不再抱怨了。
promise.Promise
看起來很怪,不像我們常用的 TypeScript 寫法,事實上,小寫的 promise為 namespace,而Promise<string>才是我們所熟悉的Promise。

藉由剛剛的經驗,將 wdpromise.Promise<any> 改成 promise.Promise<any> 試試看,結果 language service 完全不再抱怨了。

實際跑 ng e2e,TypeScript 編譯成功,也可以成功跑完測試。
實務上真的要這樣寫回傳型別嗎?
protractor/exampleTypescript/angularPage.ts
1 | // Because this file references protractor, you'll need to have it as a project |
在 Protractor 官網實際示範了應該如何用 TypeScript 寫 page object。
21 行
1 | // getGreeting returns a webdriver.promise.Promise.<string>. For simplicity |
getGreeting() 用的正是 getText(),Protractor 官方也認為 webdriver.promise.Promise.<string> 實在太麻煩了,用 any 即可。

若你跟我一樣有型別強迫症,回傳 any 即可。
Conclusion
- 雖然 TypeScript 是強型別,但
any也不是不能用,除非能說出理由,在這裡就是因為webdriver.promise.Promise.<string>實在太麻煩了,連 Protractor 官網也建議直接用any即可。