From c7c3cc8b9fbe40d09770c1926bba52db4c3e4038 Mon Sep 17 00:00:00 2001 From: Ayu Date: Wed, 1 Jan 2025 22:59:17 +0900 Subject: [PATCH] refactor: migrate to playwright (#141) --- .github/workflows/cron-run.yml | 4 ++-- .github/workflows/manual-run-force.yml | 4 ++-- .github/workflows/manual-run.yml | 4 ++-- .gitignore | 4 ++++ bun.lockb | Bin 145756 -> 118044 bytes package.json | 4 +++- src/license.ts | 14 +++++++------- src/variable-gen.ts | 8 ++++---- 8 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cron-run.yml b/.github/workflows/cron-run.yml index 840aee2..81b9f74 100644 --- a/.github/workflows/cron-run.yml +++ b/.github/workflows/cron-run.yml @@ -19,8 +19,8 @@ jobs: - name: Install run: bun install - - name: Puppeteer Setup - run: bunx @puppeteer/browsers install chrome@stable + - name: Playwright Setup + run: bunx playwright install --with-deps chromium - name: Generate API run: bun run cli generate $GOOGLE_API_KEY diff --git a/.github/workflows/manual-run-force.yml b/.github/workflows/manual-run-force.yml index e440647..b2ab17a 100644 --- a/.github/workflows/manual-run-force.yml +++ b/.github/workflows/manual-run-force.yml @@ -17,8 +17,8 @@ jobs: - name: Install run: bun install - - name: Puppeteer Setup - run: bunx @puppeteer/browsers install chrome@stable + - name: Playwright Setup + run: bunx playwright install --with-deps chromium - name: Generate API run: bun run cli generate $GOOGLE_API_KEY diff --git a/.github/workflows/manual-run.yml b/.github/workflows/manual-run.yml index 919e3a6..f4e15b5 100644 --- a/.github/workflows/manual-run.yml +++ b/.github/workflows/manual-run.yml @@ -14,8 +14,8 @@ jobs: with: bun-version: latest - - name: Puppeteer Setup - run: bunx @puppeteer/browsers install chrome@stable + - name: PLaywright Setup + run: bunx playwright install --with-deps chromium - name: Generate API run: bun run cli generate $GOOGLE_API_KEY diff --git a/.gitignore b/.gitignore index 9429846..4d02164 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,7 @@ yarn-error.log .idea dist/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/bun.lockb b/bun.lockb index f4e317e05881222c49226f8e6d1fac66b4afed17..4126592498148df146f260644b94705a6627d62a 100755 GIT binary patch delta 23831 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ℷQBCoy$!)yeA zr@Skse0K4khw+U9@>M|iRxoce>jgz%)GmpoGj_wJcd#>@cWjElB&ps@p(oe;{=R_+ zppvb6JS*wmEb2ZBL>X?vjlU?HQ z?IxSlO6nWBFbkQKQ8!tisGP)IU6{#;`o_=Y)oNJwzKEJ>pKSu zyf5iJx<{L}a(C-sisJKjHUNq#lLzrM06#;6>`!f^t_Qc~ie+o#POn&Y^gk=t4ct9V zE`y=(9KJEw(D>s5)cO6%C(hG)R%q3^Qq=h!$*XPac7#_h_qDtD&R@NGX=Y-Wx0AWIR(_eVTOKee;^z%^kHF z%r?m5>=T2uO-{t)nxknJI}sy!%!-mnW*d6YueRF$xQFw{%#h|+4V}dgkb<5RoTg}~ z`(C5WiFDPaD7-J&s7UBW^+c2g^^mTbb`-y2VLgISft*I5W=VNvNZaI?reRYg_#IO< zjieN+nwI8t#?RWy2}}}UT7K$JGNgeicB+-Ey^9o; z43`f2;Q%=v*4R&q7HqbG-fUC(q=Ju7X08*CZX}#At)-h3Lk}qq+ZQMK<+qLl%p=A| z(+18OEmByRt{`v>Qy8c#82KqFz6;MUfaI?*XcfzTn-t&OWrhI3Z_3|jus)299ql0x zWO>sVRrDD3Ca->!xdFR3P0$ZN$6|z9hhr(KL%Z}i=A)yNDiJN_Bw|4TDyhuYvVr%= z`u-1JC!G^YhGQUdIDm@n7kes3=FD)D`=D`4XjOK+Q0kR;NIVUo)p%|px)W4vEwGrf z_5&n;x|`?+nOmZ`h8ZNqxh@sfE+j|}WFQdD#XK&OuRwUa;yDNu##2@pEU(KUi3EOJ zaax2uRj86r6`#dSWDMTuw}IG&;sQ&%b0X)Hv|u(u$K+DZPLGyuqv z>PiuyIXOd_{DAYUBp+)bMxt3=ujG|q=cI) zXNB8H5f!K;iOAyf-s*9xghG~P+jdm394c*1G*FNR;EZWiikl4KITxh(L6WLa@fd(N zV8<;z2EQn*HP@>Nt4vj3v)qdCy~$tFL$Qx#ex7>b5#3M9h;Qpn@C zsF#xsS2*RKrJQ%S4q?Yp3?rsE8Wt_A22MkZ+N!0;9WBQBpe)naBuyxPQL65W_0W*X zcPo$?(%>#N3n78WsOfH&ALMQc#+JR86gMU5M9503!S%VKxY_VnW@|P#W5_M@2lbfW z-DZ@v0^!CV&BJ(g5wIU{)A(rJEnzNQ;hOFCQ7FUA*@NSmg7D_5Mp^$<*u|Gp5a6{DV&v*D$rgNw3_Yf zBgM0m>H#)c<^dBS1+F;T;m;9(6Q2-UEBxrf5rzqp5il{I0pZ&6Z?$ZfURonNm>>%S z?n4t`+!8!QIUW;YJ-|2UDh)ev>=G23uypE}p5g6}6W{z1U`QE-Hghj2LEv$PfhJjI zz5B`hn%ggB(2rc-&{ZYd-$&-M4~~nH3 zAWldRn3ozDP^k)RRua^u?QlVnRufKAbQ)e>>?UkI8aLsE!_ah#I5^N&n`Iv(`ORL< z#OAv{&Il&IEfn=wd*1&S>O4Qh^~Sybb%BcP&~W>WJQR+jfC{qo0(NitbR2Z(_V65?n$-{o@810U@?o_(E{A5L=E9)v)ziM z7T}vlVD^d?5qbyQEAlXcL%_21H3W2e6_6F=*AQkvDDTb&1TEHiEpM?149x+t9Yc(N!kE#$uh>o zH}fohoJ{CHA0x-J`oHKQA1x3Ez5a%ukjvv)4Z~rzY>4>!dk>ScFR{dHB(ERt>&gUn rXE%zzQ)FpI|EVGJ;`pgUwRq@`pVK(^HsQ;W6MpovabVZkPrv^^(mBjV diff --git a/package.json b/package.json index 4f4c246..e920d1f 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,14 @@ "p-queue": "^8.0.1", "pathe": "^1.1.2", "picocolors": "^1.1.1", - "puppeteer": "^23.11.1", + "playwright": "^1.49.1", "stylis": "^4.3.4", "zod": "^3.24.1" }, "devDependencies": { "@biomejs/biome": "1.9.4", + "@playwright/test": "^1.49.1", + "@types/bun": "latest", "@types/node": "^22.10.2", "c8": "^10.1.3", "magic-string": "^0.30.17", diff --git a/src/license.ts b/src/license.ts index c57cef8..fc004e7 100644 --- a/src/license.ts +++ b/src/license.ts @@ -4,7 +4,7 @@ import { consola } from 'consola'; import stringify from 'json-stringify-pretty-compact'; import { parseHTML } from 'linkedom'; import { dirname, join } from 'pathe'; -import puppeteer from 'puppeteer'; +import { chromium } from 'playwright'; import type { Authors, License, Licenses } from './types'; @@ -128,20 +128,20 @@ const processTable = (tableHTML: string) => { * {@link https://fonts.google.com/attribution} */ export const parseLicenses = async () => { - const browser = await puppeteer.launch({ headless: true }); + const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); // We only need html, skip css and font downloads - await page.setRequestInterception(true); - page.on('request', (request) => { + await page.route('**/*', (route) => { + const request = route.request(); if ( ['image', 'stylesheet', 'font', 'other'].includes(request.resourceType()) ) { - request.abort(); + route.abort(); } else { - request.continue(); + route.continue(); } }); - await page.goto(url, { waitUntil: 'networkidle0' }); + await page.goto(url, { waitUntil: 'networkidle' }); const tableHTML = await page.evaluate(() => { const query = document.querySelector('gf-attribution > section > table'); diff --git a/src/variable-gen.ts b/src/variable-gen.ts index 20734fd..ce0b280 100644 --- a/src/variable-gen.ts +++ b/src/variable-gen.ts @@ -6,7 +6,7 @@ import merge from 'deepmerge'; import stringify from 'json-stringify-pretty-compact'; import { parseHTML } from 'linkedom'; import { dirname, join } from 'pathe'; -import puppeteer from 'puppeteer'; +import { chromium } from 'playwright'; import type { FontObjectVariableDirect } from './types'; @@ -104,10 +104,10 @@ const processTable = (tableHTML: string) => { * {@link https://fonts.google.com/variablefonts} */ export const fetchVariable = async () => { - // Need to use Puppeteer to let JavaScript load page elements fully - const browser = await puppeteer.launch({ headless: true }); + // Need to use Playwright to let JavaScript load page elements fully + const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); - await page.goto(url, { waitUntil: 'networkidle0' }); + await page.goto(url, { waitUntil: 'networkidle' }); const tableHTML = await page.evaluate(() => { const selector = document.querySelector(