サンダルで靴屋に行ったけど試着時に靴下を貸してくれた
起こったこと
妻がサンダルを履いて買い物に出かけた。その際に靴を買うことになったが、靴下を履いていない。直で試着するのは憚れるところであった。
靴下を借りれた
「靴下がないので試着はちょっと遠慮したいです」と言ったところ「でしたら、靴下お貸ししますか?」と答えてもらえた。靴下を借りて試着を成功することができた。
htmlでホバー時に文字サイズを大きくする際、下の要素がずれるのをやめたかった
起こったこと
ホバー時に文字を大きくする処理を以下のようにCSSで書いた。
<style> .hogehoge {} .hogehoge:hover { font-size: 130%; } </style> <div class="hogehoge"> 文字を大きく </div> <p> ここはそのまま </p>
しかし、対象となる要素が増加した文字サイズ分広がっていて、下にある要素も文字サイズが増えた分下がる。かくかくしていて見栄えが良くなかった。
対処した方法
transform: scale()
を使うことにした。transform-origin
の設定も色々と変えると大きくなる起点も変えられる。うまくいかないときはこれも変えてみること。
<style> .piyopiyo {} .piyopiyo:hover { transform: scale(1.3); transform-origin: left; } </style> <div class="piyopiyo"> 文字を大きく </div> <p> ここはそのまま </p>
PlayWright+MonoRepoはどうするのがよいのだろう
monorepoとE2E
コンポーネントを共有するようなWebアプリケーションmonorepoがあるとして、これらはどのようにするのが良いのか悩んでいる(現在進行形)
こういうのにしてみたけど
monorepo/ ├── common # コンポーネントなど、projectsが呼び出す共通のデータが格納されているディレクトリ ├── e2e # テストが入ったディレクトリ └── projects # プロジェクトのモノレポ ├── hogehoge # hogehogeプロジェクト └── piypiyo # piyopiyoプロジェクト
hogehogeとpiyopiyoは似通ったシステムであり共通しているデータもあるが、それぞれ独自の機能も存在している。E2Eテストを書く場合はプロジェクトごとに書く必要がある。なお、すべてnode.js、またはtypescriptで記述されている。
e2eディレクトリには共通するテストを書き、それらは関数にて呼び出すようにする。
// e2e/toppage.test.ts import { test, expect, Page } from "@playwright/test"; export const toppageTest = (specData: any) => { test("トップページテスト1", async ({ page }) => { await page.goto("/"); // ... } ); }
projectはこれをimportして実行する。また、projectごとに行いたいテストはe2eディレクトリのnode_modules内のplaywrightをimportし、テストケースを記述する。
// projects/hogehoge/e2e/toppage.test.ts import { toppageTest } from "../../../e2e/toppage.test; import { test, expect, Page } from "../../../e2e/node_modules/@playwright/test"; const specData = {}; // hogehogeっぽいデータ toppageTest(specData); // 共通のテスト test("hogehogeプロジェクトのトップページ特有のテスト", async ({ page }) => { // hogehogeプロジェクトのトップページ特有のテスト });
これらはtypescriptで記述してあるので、tsconfig.jsonのpathsで設定を変えてあげた。
{ "compilerOptions": { "baseUrl": "./", "paths": { "@e2e": ["../../../e2e/*"], }, } }
とりあえずこういう形になった。
// projects/hogehoge/e2e/toppage.test.ts import { toppageTest } from "@e2e/toppage.test; import { test, expect, Page } from "@e2e/node_modules/@playwright/test"; const specData = {}; // hogehogeっぽいデータ toppageTest(specData); // 共通のテスト test("hogehogeプロジェクトのトップページ特有のテスト", async ({ page }) => { // hogehogeプロジェクトのトップページ特有のテスト });
なんかやりかたに進展があったらまた書いてみます。
Playwrightで非同期でボタンを複数押そうとしたら安定しなかった
version情報
"@playwright/test": "1.22.2"
起こったこと
Webアプリケーション内にあるボタンを二つ押すと遷移できるページで、非同期で二つのボタンを押そうとしたけど出来なかった。
例
前提
例えば、ボタン1とボタン2を押すと下の要素に「二つのフラグが立ちました」と表示されるWebアプリケーションがあるとする。
(ごちゃごちゃして申し訳ない)
コードではこう書いた
test("ボタンを非同期で二つ押す", async ({ page }) => { await page.goto("/"); const btn1 = page.locator(`text="ボタン1"`); const btn2 = page.locator(`text="ボタン2"`); const btns = [btn1, btn2]; await Promise.all(btns.map(async (b) => await b.click())); await expect(page.locator(".flager")).toHaveText(/二つのフラグが立ちました/); });
数回このコードで実行してみたが、Chromiumeだけ成功するパターン、firefoxだけ成功するパターンなど、いろいろと不思議なことが起きた。
こうした
test("ボタンを順繰りで二つ押す", async ({ page }) => { await page.goto("/"); const btn1 = page.locator(`text="ボタン1"`); const btn2 = page.locator(`text="ボタン2"`); const btns = [btn1, btn2]; for (let btn of btns) { await btn.click(); } await expect(page.locator(".flager")).toHaveText(/二つのフラグが立ちました/); });
こう書いたら安定した。
アプリ側の実装はこのような感じ
let flag1 = false; let flag2 = false; const btn1 = document.getElementById("button1"); const btn2 = document.getElementById("button2"); const flag1AndFlag2 = () => { if (flag1 && flag2) { const p = document.querySelector(".flager") as HTMLParagraphElement; p.innerText = "二つのフラグが立ちました"; } }; btn1?.addEventListener("click", () => { flag1 = true; flag1AndFlag2(); }); btn2?.addEventListener("click", () => { flag2 = true; flag1AndFlag2(); });
jszipで圧縮してもサイズ変わらない感じあった
version情報
"typescript": "^4.7.4" "jszip": "^3.10.1"
起こったこと
jszipを使ってzipデータを作成しようとしたらあんまり圧縮されてる感じがなかった。 stuk.github.io
import fs from "fs"; import jszip from "jszip"; import { text } from "./text"; // 60,000文字ぐらいのテキスト const zip = new jszip(); zip.file("test.txt", text); zip.generateAsync({ type: "nodebuffer" }).then((blob) => { fs.writeFileSync("test.zip", blob); });
というかオプション当てないとどうも無圧縮っぽい。
オプション当てた
{ compression: "DEFLATE"}
というオプションを当てた
defaultがSTORE (no compression)
って書いてあった
zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" }).then((blob) => { fs.writeFileSync("test.zip", blob); });
およそ七割が圧縮された
Amplifyのビルドに使ったArtifactをCLIからDownloadしたい
起こったこと
AWS Amplifyに使った過去のビルド用データが必要になった。Amplifyコンソールからダウンロードは可能。
ただCLIの「list-artifacts」には該当のArtifactは見つからない。その他、SDKからListArtifactを叩いても出てこなかった。 https://docs.aws.amazon.com/cli/latest/reference/amplify/list-artifacts.html
$ aws amplify list-artifacts --app-id ****** --branch-name ***** --job-id NUMBER { "artifacts": [] }
GetListじゃなくてGetJobだった
GetJobの方のsteps以下にあるartifactsUrl
内のURLがそのビルド用データだった。
https://docs.aws.amazon.com/cli/latest/reference/amplify/get-job.html
$ aws amplify get-job --app-id ****** --branch-name ***** --job-id NUMBER { "job": { ... "steps": [ { "stepName": "", ... "artifactsUrl": "ここのURL",
aws s3にアップロードされているデータの検索
起こったこと
AWS S3に挙げられている古いJSONデータを探す必要が出た。
awsのs3コマンドかs3cmdコマンドか
s3cmdだと深い層(再帰的)の表示が出来そうになかったのでawsコマンドを使った。軽く調べてみたレベルなのでもしかしたらきちんと調べたらs3cmdでいけるかもしれない。
こんなコマンド
$ aws s3 ls s3://****/ --recursive | sort -nr | grep hogehoge.json
ワイルドカードは使えないらしいのでパイプであれこれ渡して表示を絞った。
参考
https://stackoverflow.com/questions/32840053/amazon-s3cmd-ls https://stackoverflow.com/questions/39857802/check-if-file-exists-in-s3-using-ls-and-wildcard https://blog.hello-world.jp.net/posts/aws-4254