CypressでCognitoにログインするテストケースを通すのに苦労したポイント
概要
- cypressを初めて使う筆者が
- cognitoを認証基盤に利用するwebアプリに
- ログインするテストケースを作った際にハマったポイントまとめ
結論
ここのコードに解決策が全部入ってるからこれ見ればok
https://gist.github.com/vittorio-nardone/a9b388ff7388a4ae7343cd6a2758bc4b
背景
最初、cypressをcognitoに使った事例探したらクラメソさんの記事があって、
https://dev.classmethod.jp/articles/amplify-console-cypress/
助かったー、と思いつつ参考にして実践してみたがだめだったので、色々と試行錯誤した軌跡
ハマったポイント
セレクタで入力フォームを取得できない
ログイン画面を表示させて、inputタグに入力すべくセレクタで指定したが、見つからないエラー
describe("Login Test", () => {
it('Shows Login', () =>
cy.visit('https://xxxx/login')
cy.get('[data-test="sign-in-username-input"]')
})
}
これを実行すると、見つかりません、と言われます。
Timed out retrying after 4000ms: Expected to find element: [data-test="sign-in-username-input"], but never found it.
入力フォームのタグを確認したら data-test="sign-in-username-input"
要素は間違いなくある
<input id="username" type="text" placeholder="xxx" class="input" data-test="sign-in-username-input">
なのになぜ?
iframeの影響か?いや使ってないな、とか
タグが深くなったら届かない?とか
amplify-sign-in
タグまで辿れてその先の amplify-form-section
が辿れないのなんでやとか
色々調べましたが、解決には至らない
キレてる。怖い。
解決策
cypressのgetにオプション { includeShadowDom: true }
をつけて解決しました。
cy.get('[data-test="sign-in-username-input"]', { includeShadowDom: true })
参考) https://docs.cypress.io/api/commands/get.html#Arguments
原因
コンソールログを見ると #shadow-root(open)
って表記があります。
なんそれ
コンポーネントっぽくDOMを利用できるっぽいなにからしい(かなり浅い理解
まあ、なんせshadowって言ってるぐらいなんで、隠れてるんでしょうね。なので、セレクタが見つけれなかったと。
で、それでも見つけてくれるオプション includeShadowDom
ができたと。
デフォルト true
じゃあかん?
と思ったら、configurationにあるので変えれそう
パスワード入力フォームにtypeできない
ログインIDはセレクタで取得しtypeで入力できたので、次パスワード、と意気込むとこのエラーがでました。
cy.type() failed because it targeted a disabled element.
> <input id="password" type="password" placeholder="パスワード" class="input" data-test="sign-in-password-input">
Ensure the element does not have an attribute named disabled before typing into it.
なんか途中のinputタグの表現がキレてる。今度は私じゃなくてタグがキレてる。怖い。
エラー文にあるような、 disabled
な要素になってないのは確認した。
で、ググってみると同様の現象はあるようで、以下のように解決してた。
cy.get('[slot="sign-in"]').find('#password', { includeShadowDom: true }).click({force: true})
cy.get('[slot="sign-in"]').find('#password', { includeShadowDom: true }).type('password')
一回 .click({force: true})
で強制クリックでフォーカスしておいて type() すると。なるほど。
これで動作した。
が、結論にのせたgistにもっとスマートな方法があった
cy.get('[slot="sign-in"]').find('#password',{ includeShadowDom: true } ).type('password', {log: false, force: true})
type() に force:true
optionあるやん。1行ですむやん。素敵やん。
ローカル環境でAPIリクエストが502 Bad Gateway
これらをクリアし、いざログインしてみると、
なぜかAPIリクエストのレスポンスが502 Bad Gateway で返ってくる。ちなみに以下のような構成。
- AWS上の開発環境だと問題なかった
- Cognitoから返ってきてるIdTokenの中身をdecodeしてみたが、開発環境とほぼ変わらず問題なさそうに見えた
もちろん、素のchromeだと期待通り動作する。
なので、違うのはブラウザの違いぐらいかな、とか思いながらまだ未解決
追記)解決した
原因
認可処理で、アプリケーション(lambda) で受け取る変数 event.header.Authorization
が、
cypress上のブラウザからのリクエストだと event.header.authorization
になってた。
cypressが投げるリクエストヘッダは Authorization
なので、何故、誰が小文字にしたのかは謎。
ServerlessFrameworkをローカルで動かすプラグインservlerless framework offlineのせいかな・・・?
Author And Source
この問題について(CypressでCognitoにログインするテストケースを通すのに苦労したポイント), 我々は、より多くの情報をここで見つけました https://qiita.com/papettoTV/items/0e90646c0667cdfcc79f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .