[{"data":1,"prerenderedAt":896},["ShallowReactive",2],{"content-/dependabot-and-e2e-stabilization":3,"all-pages-for-dir":894,"og-image-/dependabot-and-e2e-stabilization":895},{"id":4,"title":5,"body":6,"category":877,"description":878,"extension":879,"meta":880,"navigation":517,"ogImage":881,"path":882,"project_name":883,"published":884,"publishedAt":885,"seo":886,"stem":887,"tags":888,"todo":881,"unpublished":884,"updatedAt":881,"__hash__":893},"pages/2026-05/2026-05-02/dependabot-and-e2e-stabilization.md","Dependabot 6PRをpnpm overrides統合PRに集約し、PlaywrightのnetworkidleをCodexレビューで全削除した日",{"type":7,"value":8,"toc":864},"minimark",[9,30,35,57,64,68,75,154,164,167,171,174,199,202,205,212,223,373,382,388,391,397,423,426,430,437,440,444,459,564,567,585,588,652,657,661,666,672,784,789,799,803,809,812,815,844,854,860],[10,11,12,13,17,18,21,22,25,26,29],"p",{},"eurekapu-nuxt4でDependabotが7本のPRを開きっぱなしにしていて、全部CIが赤だった。順次rebaseで潰そうとしたら同じpeer依存解決で永遠にループに入りそうになったので、",[14,15,16],"code",{},"pnpm overrides"," で4ライブラリを一気に固定する統合PRに切り替えて1本でマージ。さらにE2Eのフレーキー原因だった ",[14,19,20],{},"waitForLoadState('networkidle')"," をCodex（GPT-5.5）レビューで「SPA遷移後のloadは再発火しないから無意味」と一刀両断され、25箇所まるごと削除。Nuxtのハイドレート前にclickが空振りする3件を ",[14,23,24],{},"expect(...).toBeVisible()"," の暗黙待機 + ",[14,27,28],{},"expect.toPass({ timeout })"," のretryで包んで恒久対策、最終的にCIで全パス、脆弱性73→70、PR #15までマージで一日が終わった。",[31,32,34],"h2",{"id":33},"朝-svg表示崩れの調査からスタート","朝: SVG表示崩れの調査からスタート",[10,36,37,38,41,42,45,46,49,50,52,53,56],{},"いつも通りローカルでビルド確認していたら、トップページに紐づく ",[14,39,40],{},"contents.vue"," のSVGが本番で表示崩れしていることに気付いた。原因を辿ると、",[14,43,44],{},"public/images/excel/**"," が ",[14,47,48],{},".gitignore"," で除外されているのに、",[14,51,40],{}," だけが相対パスで ",[14,54,55],{},"public/images/excel/..."," を参照していた。mainブランチのCIではビルド時にファイルが存在しないので空SVG扱いになっていた。",[10,58,59,60,63],{},"該当SVGをR2配信のURLに差し替えてビルドを通した。コミットして ",[14,61,62],{},"chore/deps-batch-bump"," ブランチにpushしようとして、ここで一つ目の事故が起きる。",[31,65,67],{"id":66},"e2eテストの期待値が実態とズレていた","E2Eテストの期待値が実態とズレていた",[10,69,70,71,74],{},"ついでにローカルで ",[14,72,73],{},"pnpm test:e2e"," を回したら、トップページのテストが落ちていた。",[76,77,82],"pre",{"className":78,"code":79,"language":80,"meta":81,"style":81},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// テストコード\nexpect(await page.locator('.card').count()).toBe(6) // ドラフト枠込みの想定\n","typescript","",[14,83,84,93],{"__ignoreMap":81},[85,86,89],"span",{"class":87,"line":88},"line",1,[85,90,92],{"class":91},"sxvE3","// テストコード\n",[85,94,96,100,104,108,112,115,118,120,124,128,130,133,136,139,142,144,148,151],{"class":87,"line":95},2,[85,97,99],{"class":98},"senZ8","expect",[85,101,103],{"class":102},"shFtX","(",[85,105,107],{"class":106},"sHkkW","await",[85,109,111],{"class":110},"s4oTP"," page",[85,113,114],{"class":102},".",[85,116,117],{"class":98},"locator",[85,119,103],{"class":102},[85,121,123],{"class":122},"sMJiu","'",[85,125,127],{"class":126},"sdGka",".card",[85,129,123],{"class":122},[85,131,132],{"class":102},").",[85,134,135],{"class":98},"count",[85,137,138],{"class":102},"()).",[85,140,141],{"class":98},"toBe",[85,143,103],{"class":102},[85,145,147],{"class":146},"sM54T","6",[85,149,150],{"class":102},")",[85,152,153],{"class":91}," // ドラフト枠込みの想定\n",[10,155,156,157,159,160,163],{},"実際のトップページには ",[14,158,127],{}," が5枚しか描画されていない。ドラフト枠を含む期待値だったが、ドラフト枠の表示は別ルートに移っていて、このテストの想定だけが古いままだった。実態に合わせて ",[14,161,162],{},"toBe(5)"," に直して終了。",[10,165,166],{},"E2Eが落ちている本丸はこの後ろにいる。",[31,168,170],{"id":169},"dependabot-7prが全部赤のまま放置されていた","Dependabot 7PRが全部赤のまま放置されていた",[10,172,173],{},"朝の修正作業中にDependabotのPR一覧を確認したら、7本ともCIが赤になっている。",[175,176,177,181,184,187,190,193,196],"ul",{},[178,179,180],"li",{},"PR #6: postcss",[178,182,183],{},"PR #7: simple-git",[178,185,186],{},"PR #8: defu",[178,188,189],{},"PR #9: vite",[178,191,192],{},"PR #10: drizzle-orm",[178,194,195],{},"PR #11: lodash",[178,197,198],{},"PR #12: 別ライブラリ",[10,200,201],{},"順次rebaseで潰そうと最初にPR #6（postcss）とPR #7（simple-git）からマージした。これは素直に通った。脆弱性が73→70に減る。残り4本（defu / vite / drizzle-orm / lodash）に手を付けたところで気付く。",[10,203,204],{},"それぞれのPRが微妙に被るpeer依存を持っていて、片方をrebaseするともう片方のlockfileが壊れる。順次マージしていくと、最後の1本にたどり着くまでに残り3本を毎回rebaseし直すループに入る。Dependabotのrebase待ちが直列で積み上がり、CIキューが詰まる。",[31,206,208,209,211],{"id":207},"統合pr-13で-pnpm-overrides-一発固定に切り替え","統合PR #13で ",[14,210,16],{}," 一発固定に切り替え",[10,213,214,215,218,219,222],{},"ループを断ち切るため、4ライブラリを一気に固定する統合PRに切り替えた。",[14,216,217],{},"package.json"," に ",[14,220,221],{},"pnpm.overrides"," でバージョンを固定する。",[76,224,228],{"className":225,"code":226,"language":227,"meta":81,"style":81},"language-json shiki shiki-themes vitesse-light vitesse-light","{\n  \"pnpm\": {\n    \"overrides\": {\n      \"defu\": \"^6.1.4\",\n      \"vite\": \"^7.1.12\",\n      \"drizzle-orm\": \"^0.44.6\",\n      \"lodash\": \"^4.17.21\"\n    }\n  }\n}\n","json",[14,229,230,235,254,269,293,314,335,355,361,367],{"__ignoreMap":81},[85,231,232],{"class":87,"line":88},[85,233,234],{"class":102},"{\n",[85,236,237,241,245,248,251],{"class":87,"line":95},[85,238,240],{"class":239},"sqvqQ","  \"",[85,242,244],{"class":243},"sz8Xr","pnpm",[85,246,247],{"class":239},"\"",[85,249,250],{"class":102},":",[85,252,253],{"class":102}," {\n",[85,255,257,260,263,265,267],{"class":87,"line":256},3,[85,258,259],{"class":239},"    \"",[85,261,262],{"class":243},"overrides",[85,264,247],{"class":239},[85,266,250],{"class":102},[85,268,253],{"class":102},[85,270,272,275,278,280,282,285,288,290],{"class":87,"line":271},4,[85,273,274],{"class":239},"      \"",[85,276,277],{"class":243},"defu",[85,279,247],{"class":239},[85,281,250],{"class":102},[85,283,284],{"class":122}," \"",[85,286,287],{"class":126},"^6.1.4",[85,289,247],{"class":122},[85,291,292],{"class":102},",\n",[85,294,296,298,301,303,305,307,310,312],{"class":87,"line":295},5,[85,297,274],{"class":239},[85,299,300],{"class":243},"vite",[85,302,247],{"class":239},[85,304,250],{"class":102},[85,306,284],{"class":122},[85,308,309],{"class":126},"^7.1.12",[85,311,247],{"class":122},[85,313,292],{"class":102},[85,315,317,319,322,324,326,328,331,333],{"class":87,"line":316},6,[85,318,274],{"class":239},[85,320,321],{"class":243},"drizzle-orm",[85,323,247],{"class":239},[85,325,250],{"class":102},[85,327,284],{"class":122},[85,329,330],{"class":126},"^0.44.6",[85,332,247],{"class":122},[85,334,292],{"class":102},[85,336,338,340,343,345,347,349,352],{"class":87,"line":337},7,[85,339,274],{"class":239},[85,341,342],{"class":243},"lodash",[85,344,247],{"class":239},[85,346,250],{"class":102},[85,348,284],{"class":122},[85,350,351],{"class":126},"^4.17.21",[85,353,354],{"class":122},"\"\n",[85,356,358],{"class":87,"line":357},8,[85,359,360],{"class":102},"    }\n",[85,362,364],{"class":87,"line":363},9,[85,365,366],{"class":102},"  }\n",[85,368,370],{"class":87,"line":369},10,[85,371,372],{"class":102},"}\n",[10,374,375,376,378,379,381],{},"ここで一つ判断ポイントが出た。",[14,377,300],{}," はDependabotがメジャー8系を提案してきていたが、Vite 8への移行は破壊的変更が多く、Nuxt側のpeer互換も怪しい。dependabotの差分を確認して、7系最新の ",[14,380,309],{}," に固定する方針に切り替えた。",[10,383,384,387],{},[14,385,386],{},"pnpm install"," でlockfile再生成、ビルド・テストを通して、4本のDependabot PRをcloseできる統合PR #13として作成した。",[31,389,390],{"id":390},"別セッションがブランチ衝突を起こしていた",[10,392,393,394,396],{},"統合PR #13をpushしようとしたら、別セッション（朝のSVG修正側）が同じ ",[14,395,62],{}," ブランチで作業を進めていた。SVG側のコミットが先にpushされていて、自分の手元の変更とコンフリクトする。",[10,398,399,400,402,403,406,407,410,411,414,415,418,419,422],{},"別セッションへ手紙を書いた。「",[14,401,62],{}," でpnpm overrides作業中。SVG修正は別ブランチに退避してほしい」と ",[14,404,405],{},"internal/2026-05-02/"," にメモを置く。並行してこちらは ",[14,408,409],{},"git reset --soft HEAD~N"," で自分の変更をindexに戻し、新ブランチ ",[14,412,413],{},"chore/deps-overrides-bump"," に移管した。",[14,416,417],{},"reset --soft"," を選んだのは作業内容を絶対に失いたくなかったからで、",[14,420,421],{},"--hard"," だと未コミットの修正が消えるリスクがある。",[10,424,425],{},"新ブランチでpush、PR #13としてcleanにオープンし直した。CIを通して、Squash and mergeで取り込んだ。",[31,427,429],{"id":428},"並行してpr-14-簿記3級ノート9章移植","並行してPR #14: 簿記3級ノート9章移植",[10,431,432,433,436],{},"別件で進めていた簿記3級ノート9章のVue移植 + SVGレビュー反映が固まっていたので、PR #14として上げた。E2EがCIで1件だけ失敗する。",[14,434,435],{},"/quiz/random"," の遷移テストで、ロードに時間がかかってタイムアウトしていた。",[10,438,439],{},"ローカルでretryすると通る。明らかにフレーキー。再度CI回すと通ったので Squash and merge した。ただしフレーキーを放置すると後で必ず効いてくる。ユーザーから「恒久対策をPRで切ってくれ」とリクエストが来たので、PR #15を立てる。",[31,441,443],{"id":442},"pr-15-networkidleを25箇所から全削除","PR #15: networkidleを25箇所から全削除",[10,445,446,447,450,451,454,455,458],{},"E2Eテスト全体を眺めると、",[14,448,449],{},"page.waitForLoadState('networkidle')"," がSPAページ遷移直後に大量に書かれていた。4ファイル25箇所。最初は「",[14,452,453],{},"networkidle"," は重いから ",[14,456,457],{},"load"," に置換しよう」と全置換した。",[76,460,462],{"className":78,"code":461,"language":80,"meta":81,"style":81},"// Before\nawait page.goto('/quiz')\nawait page.waitForLoadState('networkidle')\n\n// After（最初の修正案）\nawait page.goto('/quiz')\nawait page.waitForLoadState('load')\n",[14,463,464,469,492,513,519,524,544],{"__ignoreMap":81},[85,465,466],{"class":87,"line":88},[85,467,468],{"class":91},"// Before\n",[85,470,471,473,475,477,480,482,484,487,489],{"class":87,"line":95},[85,472,107],{"class":106},[85,474,111],{"class":110},[85,476,114],{"class":102},[85,478,479],{"class":98},"goto",[85,481,103],{"class":102},[85,483,123],{"class":122},[85,485,486],{"class":126},"/quiz",[85,488,123],{"class":122},[85,490,491],{"class":102},")\n",[85,493,494,496,498,500,503,505,507,509,511],{"class":87,"line":256},[85,495,107],{"class":106},[85,497,111],{"class":110},[85,499,114],{"class":102},[85,501,502],{"class":98},"waitForLoadState",[85,504,103],{"class":102},[85,506,123],{"class":122},[85,508,453],{"class":126},[85,510,123],{"class":122},[85,512,491],{"class":102},[85,514,515],{"class":87,"line":271},[85,516,518],{"emptyLinePlaceholder":517},true,"\n",[85,520,521],{"class":87,"line":295},[85,522,523],{"class":91},"// After（最初の修正案）\n",[85,525,526,528,530,532,534,536,538,540,542],{"class":87,"line":316},[85,527,107],{"class":106},[85,529,111],{"class":110},[85,531,114],{"class":102},[85,533,479],{"class":98},[85,535,103],{"class":102},[85,537,123],{"class":122},[85,539,486],{"class":126},[85,541,123],{"class":122},[85,543,491],{"class":102},[85,545,546,548,550,552,554,556,558,560,562],{"class":87,"line":337},[85,547,107],{"class":106},[85,549,111],{"class":110},[85,551,114],{"class":102},[85,553,502],{"class":98},[85,555,103],{"class":102},[85,557,123],{"class":122},[85,559,457],{"class":126},[85,561,123],{"class":122},[85,563,491],{"class":102},[10,565,566],{},"念のためCodex（GPT-5.5）にレビューを投げた。返ってきた指摘が一刀両断だった。",[568,569,570],"blockquote",{},[10,571,572,573,575,576,578,579,581,582,584],{},"SPAでルートを切り替えた場合、",[14,574,457],{}," イベントは初回ナビゲーション時にしか発火しない。SPA内遷移では ",[14,577,457],{}," も ",[14,580,453],{}," も再発火せず、",[14,583,502],{}," を呼ぶと即座にresolveするか、最初のloadイベントを参照したまま無意味に待つ。これは恒久対策にならない。削除して、要素のvisibleで暗黙的に待つべき。",[10,586,587],{},"その通りだった。25箇所全削除して、要素ベースの待機に切り替えた。",[76,589,591],{"className":78,"code":590,"language":80,"meta":81,"style":81},"// After（最終案）\nawait page.goto('/quiz')\nawait expect(page.locator('.quiz-question')).toBeVisible()\n",[14,592,593,598,618],{"__ignoreMap":81},[85,594,595],{"class":87,"line":88},[85,596,597],{"class":91},"// After（最終案）\n",[85,599,600,602,604,606,608,610,612,614,616],{"class":87,"line":95},[85,601,107],{"class":106},[85,603,111],{"class":110},[85,605,114],{"class":102},[85,607,479],{"class":98},[85,609,103],{"class":102},[85,611,123],{"class":122},[85,613,486],{"class":126},[85,615,123],{"class":122},[85,617,491],{"class":102},[85,619,620,622,625,627,630,632,634,636,638,641,643,646,649],{"class":87,"line":256},[85,621,107],{"class":106},[85,623,624],{"class":98}," expect",[85,626,103],{"class":102},[85,628,629],{"class":110},"page",[85,631,114],{"class":102},[85,633,117],{"class":98},[85,635,103],{"class":102},[85,637,123],{"class":122},[85,639,640],{"class":126},".quiz-question",[85,642,123],{"class":122},[85,644,645],{"class":102},")).",[85,647,648],{"class":98},"toBeVisible",[85,650,651],{"class":102},"()\n",[10,653,654,656],{},[14,655,24],{}," はPlaywrightが自動でretryしてくれるので、ハイドレート完了を実質的に待つことになる。",[31,658,660],{"id":659},"ハイドレート前clickをexpecttopassでretry","ハイドレート前clickをexpect.toPassでretry",[10,662,663,665],{},[14,664,453],{}," を消した後も、3件のテストがハイドレート前にclickが空振りして落ちていた。Nuxtがhydrate完了する前にPlaywrightがclickを発火させると、Vueのイベントリスナーがまだバインドされていないため何も起きない。",[10,667,668,669,671],{},"これを ",[14,670,28],{}," でretryするパターンに直した。",[76,673,675],{"className":78,"code":674,"language":80,"meta":81,"style":81},"await expect(async () => {\n  await page.locator('.btn-start').click()\n  await expect(page).toHaveURL(/\\/quiz\\/start/)\n}).toPass({ timeout: 10_000 })\n",[14,676,677,697,724,761],{"__ignoreMap":81},[85,678,679,681,683,685,689,692,695],{"class":87,"line":88},[85,680,107],{"class":106},[85,682,624],{"class":98},[85,684,103],{"class":102},[85,686,688],{"class":687},"stQ0i","async",[85,690,691],{"class":102}," ()",[85,693,694],{"class":102}," =>",[85,696,253],{"class":102},[85,698,699,702,704,706,708,710,712,715,717,719,722],{"class":87,"line":95},[85,700,701],{"class":106},"  await",[85,703,111],{"class":110},[85,705,114],{"class":102},[85,707,117],{"class":98},[85,709,103],{"class":102},[85,711,123],{"class":122},[85,713,714],{"class":126},".btn-start",[85,716,123],{"class":122},[85,718,132],{"class":102},[85,720,721],{"class":98},"click",[85,723,651],{"class":102},[85,725,726,728,730,732,734,736,739,741,744,748,752,754,757,759],{"class":87,"line":256},[85,727,701],{"class":106},[85,729,624],{"class":98},[85,731,103],{"class":102},[85,733,629],{"class":110},[85,735,132],{"class":102},[85,737,738],{"class":98},"toHaveURL",[85,740,103],{"class":102},[85,742,743],{"class":122},"/",[85,745,747],{"class":746},"svWSF","\\/",[85,749,751],{"class":750},"sLkVR","quiz",[85,753,747],{"class":746},[85,755,756],{"class":750},"start",[85,758,743],{"class":122},[85,760,491],{"class":102},[85,762,763,766,769,772,775,778,781],{"class":87,"line":271},[85,764,765],{"class":102},"}).",[85,767,768],{"class":98},"toPass",[85,770,771],{"class":102},"({ ",[85,773,774],{"class":243},"timeout",[85,776,777],{"class":102},": ",[85,779,780],{"class":146},"10_000",[85,782,783],{"class":102}," })\n",[10,785,786,788],{},[14,787,768],{}," はブロック全体を失敗時にretryしてくれる。clickが空振りしてURLが変わらなければ、再度clickしてくれる。これでハイドレート競合が消えた。",[10,790,791,794,795,798],{},[14,792,793],{},"error.vue"," の404ボタンも同様で、Vueのhydrate前にイベントが発火しないため、",[14,796,797],{},"click() → URL待ち"," の組をtoPassで包んだ。",[31,800,802],{"id":801},"結果-3536-pass-フレーキー1件","結果: 35/36 pass + フレーキー1件",[10,804,805,806,808],{},"ローカルで35/36 pass。残る1件は ",[14,807,435],{}," ページのロード遅延で、別問題（ページ自体の初期化が遅い）として切り離した。CIに投げたら全パス。PR #15をmergeして閉じた。",[31,810,811],{"id":811},"振り返り",[10,813,814],{},"今日の試行錯誤を時系列で並べると、判断の切り替えが3回あった。",[816,817,818,825,838],"ol",{},[178,819,820,824],{},[821,822,823],"strong",{},"順次rebase → pnpm overrides統合PR",": Dependabot 4本を順番に潰そうとしたら依存ループに入りかけた。「1本ずつ正しく」より「全部一発で固定する」方が早いと気付いた瞬間に方針転換した",[178,826,827,830,831,833,834,837],{},[821,828,829],{},"別セッション衝突 → reset --soft で安全退避",": 同じブランチで2セッション動かすと必ず事故る。",[14,832,421],{}," ではなく ",[14,835,836],{},"--soft"," を選んだことで作業内容を失わずに済んだ",[178,839,840,843],{},[821,841,842],{},"networkidle置換 → 全削除",": 「重いから軽い方に」という発想が、Codexレビューで「そもそも無意味」とひっくり返された。一段深い理解（SPAではload系イベントが再発火しない）に到達できたのはレビューのおかげ",[10,845,846,847,849,850,853],{},"E2Eのフレーキー対策で ",[14,848,502],{}," を入れていた時期が長かったが、SPAでは要素ベースの待機 + ",[14,851,852],{},"expect.toPass"," の方が筋がいい。ハイドレート前にclickしても落ちないようretryで包む、というパターンは他のNuxt製E2Eにもそのまま転用できる。",[10,855,856,857,859],{},"Dependabot側は、PRが3本以上溜まったら順次マージではなく最初から ",[14,858,16],{}," 統合PRを検討する運用に切り替える。今日のように依存ループに入ってから気付くと、無駄なrebaseで時間を溶かす。",[861,862,863],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqvqQ, html code.shiki .sqvqQ{--shiki-default:#99841877;--shiki-dark:#99841877}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .svWSF, html code.shiki .svWSF{--shiki-default:#BDA437;--shiki-dark:#BDA437}html pre.shiki code .sLkVR, html code.shiki .sLkVR{--shiki-default:#AB5E3F;--shiki-dark:#AB5E3F}",{"title":81,"searchDepth":95,"depth":95,"links":865},[866,867,868,869,871,872,873,874,875,876],{"id":33,"depth":95,"text":34},{"id":66,"depth":95,"text":67},{"id":169,"depth":95,"text":170},{"id":207,"depth":95,"text":870},"統合PR #13で pnpm overrides 一発固定に切り替え",{"id":390,"depth":95,"text":390},{"id":428,"depth":95,"text":429},{"id":442,"depth":95,"text":443},{"id":659,"depth":95,"text":660},{"id":801,"depth":95,"text":802},{"id":811,"depth":95,"text":811},"dev","eurekapu-nuxt4でCI赤が常態化していたDependabot7PRを統合PR1本に集約し、E2Eのフレーキー要因だったwaitForLoadState('networkidle')をCodexレビュー指摘で全削除、ハイドレート前のclick失敗をexpect.toPassでretryする恒久対策まで。","md",{},null,"/dependabot-and-e2e-stabilization","eurekapu-nuxt4",false,"2026-05-02T00:00:00.000Z",{"title":5,"description":878},"2026-05/2026-05-02/dependabot-and-e2e-stabilization",[889,16,890,891,892],"Dependabot","Playwright","E2Eテスト","Codexレビュー","zfZyN9FeCwqrKxctEJzFPJhoNOxvnrgUwEbrL1AkHlA",[],"https://log.eurekapu.com/og/blog/dependabot-and-e2e-stabilization.png?v=2026-05-02T00%3A00%3A00.000Z&title=Dependabot%206PR%E3%82%92pnpm%20overrides%E7%B5%B1%E5%90%88PR%E3%81%AB%E9%9B%86%E7%B4%84%E3%81%97%E3%80%81Playwright%E3%81%AEnetworkidle%E3%82%92Codex%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%A7%E5%85%A8%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E6%97%A5&author=Kei%20Komatsu&sig=df52581408f6daec",1782528831876]