ReactNを露出するで、コンソールでsetGlobalして、コンポーネントの側のuseGlobalが変更を検知して再描画するところまでできた。 しかしsetGlobalをCypressのテストコード内から呼び出すと、更新が検知されない。
解決編 これはiframeによってコンテキストが分かれてることとは無関係で、非同期周りの挙動だった
最小限のコードで解説する まずシンプルなコンポーネント、useEffectでsetGlobalする(1) App.tsx
function App() {
const [fusens] = useGlobal("fusens");
console.log("render");
useEffect(() => {
console.log("useEffect");
window.movidea.callSetGlobal(); // (1)
}, []);
return (...);
}
この時、コンポーネントの本体が走った後、useEffectが走り、その中でsetGlobalされ、それを検知して再描画される :
render
useEffect
call setGlobal
render
では(1)をコメントアウトし、テストケースの側でsetGlobalしたらどうなるか(2) test.js
describe('adjust font size', () => {
beforeEach(() => {
cy.visit('/')
cy.window().its('movidea').then(movidea => {
console.log("movidea resolved")
movidea.callSetGlobal() // (2)
});
})...
この時、初回の描画の後、useEffectが呼ばれるよりも前にsetGlobalが呼ばれ、この更新が検知されない :
render
movidea resolved
call setGlobal
useEffect
この(2)の呼び出しにsetTimeoutを挟んで非同期にするとどうなるか(3) test.js
describe('adjust font size', () => {
beforeEach(() => {
cy.visit('/')
cy.window().its('movidea').then(movidea => {
console.log("movidea resolved")
setTimeout(movidea.callSetGlobal, 0) // (3)
});
})...
この場合はsetGlobalが呼ばれるのがuseEffectの後になり、期待通りに変更が検知され、再描画される :
render
movidea resolved
useEffect
call setGlobal
render
というわけでワークアラウンドとしてはテストケースからの状態更新を非同期にすれば良いということになるが、微妙な解決策だなぁ
--- log Testing Redux Store
ReactNでも明示的にストアを作成することに相当するこれをやってみたけど期待通りにいかない https://github.com/CharlesStover/reactn/blob/master/Provider.md
わかったこと
わからないこと
うーむ、テストケースから状態をいじって表示をテストするってのができたらいいなと思ったのだが…