diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index b75bb90fb2..0008b5cf4c 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -128,18 +128,32 @@ jobs: pattern: blob-report-* merge-multiple: true + - name: Check if blob reports exist + id: check-blob-reports + run: | + if [ -d "all-blob-reports" ] && [ "$(ls -A all-blob-reports)" ]; then + echo "has-reports=true" >> "$GITHUB_OUTPUT" + else + echo "has-reports=false" >> "$GITHUB_OUTPUT" + mkdir -p all-blob-reports + fi + - name: Merge into HTML Report + if: steps.check-blob-reports.outputs.has-reports == 'true' run: npx playwright merge-reports --reporter html ./all-blob-reports - name: Merge into JSON Report + if: steps.check-blob-reports.outputs.has-reports == 'true' run: npx playwright merge-reports --reporter json ./all-blob-reports > playwright-results.json - uses: actions/upload-artifact@v6 + if: steps.check-blob-reports.outputs.has-reports == 'true' with: name: playwright-report path: playwright-report/ - uses: actions/upload-artifact@v6 + if: steps.check-blob-reports.outputs.has-reports == 'true' with: name: playwright-results-json path: playwright-results.json @@ -152,6 +166,9 @@ jobs: pattern: playwright-screenshots-* merge-multiple: true + - name: Ensure screenshots directory exists + run: mkdir -p test/playwright/__screenshots__ + - uses: actions/upload-artifact@v6 with: name: playwright-screenshots @@ -168,7 +185,7 @@ jobs: - name: '[PR] Calculate if any shard failed to download master screenshots' run: | - if grep -q "failure" master-screenshots-outcomes/*; then + if [ -d "master-screenshots-outcomes" ] && [ "$(ls -A master-screenshots-outcomes)" ] && grep -q "failure" master-screenshots-outcomes/* 2>/dev/null; then echo "failure" > master-screenshots-outcome else echo "success" > master-screenshots-outcome @@ -191,7 +208,12 @@ jobs: merge-multiple: true - name: Merge playwright output files - run: cat playwright-outputs/* > playwright-output + run: | + if [ -d "playwright-outputs" ] && [ "$(ls -A playwright-outputs)" ]; then + cat playwright-outputs/* > playwright-output + else + touch playwright-output + fi - uses: actions/upload-artifact@v6 with: diff --git a/.gitignore b/.gitignore index 74b9494584..a42a95a641 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,9 @@ dictionaries/ /playwright-report/ /playwright/.cache/ /test/playwright/__screenshots__/ +/.playwright-user-data/ ext/manifest.json ext/lib/* +actionlint diff --git a/innocent_corpus.zip b/innocent_corpus.zip new file mode 100644 index 0000000000..7383134ebf Binary files /dev/null and b/innocent_corpus.zip differ diff --git a/jmdict_dutch.zip b/jmdict_dutch.zip new file mode 100644 index 0000000000..4e27747234 Binary files /dev/null and b/jmdict_dutch.zip differ diff --git a/jmdict_english.zip b/jmdict_english.zip new file mode 100644 index 0000000000..c27dd952ab Binary files /dev/null and b/jmdict_english.zip differ diff --git a/jmdict_french.zip b/jmdict_french.zip new file mode 100644 index 0000000000..0295801e82 Binary files /dev/null and b/jmdict_french.zip differ diff --git a/jmdict_german.zip b/jmdict_german.zip new file mode 100644 index 0000000000..f097740085 Binary files /dev/null and b/jmdict_german.zip differ diff --git a/jmdict_hungarian.zip b/jmdict_hungarian.zip new file mode 100644 index 0000000000..ab74a953e8 Binary files /dev/null and b/jmdict_hungarian.zip differ diff --git a/jmdict_russian.zip b/jmdict_russian.zip new file mode 100644 index 0000000000..da81cd3098 Binary files /dev/null and b/jmdict_russian.zip differ diff --git a/jmdict_slovenian.zip b/jmdict_slovenian.zip new file mode 100644 index 0000000000..527ad9e139 Binary files /dev/null and b/jmdict_slovenian.zip differ diff --git a/jmdict_spanish.zip b/jmdict_spanish.zip new file mode 100644 index 0000000000..3a75a234e7 Binary files /dev/null and b/jmdict_spanish.zip differ diff --git a/jmdict_swedish.zip b/jmdict_swedish.zip new file mode 100644 index 0000000000..c7e27302a8 Binary files /dev/null and b/jmdict_swedish.zip differ diff --git a/jmnedict.zip b/jmnedict.zip new file mode 100644 index 0000000000..dcd3225ed7 Binary files /dev/null and b/jmnedict.zip differ diff --git a/kanjidic_english.zip b/kanjidic_english.zip new file mode 100644 index 0000000000..20f1d4ff9c Binary files /dev/null and b/kanjidic_english.zip differ diff --git a/kanjidic_french.zip b/kanjidic_french.zip new file mode 100644 index 0000000000..3ba0bfa077 Binary files /dev/null and b/kanjidic_french.zip differ diff --git a/kanjidic_portuguese.zip b/kanjidic_portuguese.zip new file mode 100644 index 0000000000..bd670ca3e2 Binary files /dev/null and b/kanjidic_portuguese.zip differ diff --git a/kanjidic_spanish.zip b/kanjidic_spanish.zip new file mode 100644 index 0000000000..ff56707345 Binary files /dev/null and b/kanjidic_spanish.zip differ diff --git a/kanjium_pitch_accents.zip b/kanjium_pitch_accents.zip new file mode 100644 index 0000000000..5609dccbe2 Binary files /dev/null and b/kanjium_pitch_accents.zip differ diff --git a/kireicake.zip b/kireicake.zip new file mode 100644 index 0000000000..b42ae13d71 Binary files /dev/null and b/kireicake.zip differ diff --git a/test/playwright/playwright-util.js b/test/playwright/playwright-util.js index c898f4a19c..29c2a5c9b9 100644 --- a/test/playwright/playwright-util.js +++ b/test/playwright/playwright-util.js @@ -27,10 +27,11 @@ export const test = base.extend({ // eslint-disable-next-line no-empty-pattern context: async ({}, /** @type {(r: import('playwright').BrowserContext) => Promise} */ use) => { const pathToExtension = path.join(root, 'ext'); - const context = await chromium.launchPersistentContext('', { - // Disabled: headless: false, + // Use a temp directory for user data + const userDataDir = path.join(root, '.playwright-user-data'); + const context = await chromium.launchPersistentContext(userDataDir, { + headless: false, // Extensions don't work properly in headless mode args: [ - '--headless=new', `--disable-extensions-except=${pathToExtension}`, `--load-extension=${pathToExtension}`, ], diff --git a/test/playwright/visual.spec.js b/test/playwright/visual.spec.js index 381544ebb9..f597f7a82a 100644 --- a/test/playwright/visual.spec.js +++ b/test/playwright/visual.spec.js @@ -23,8 +23,17 @@ import {expect, root, test} from './playwright-util.js'; test.beforeEach(async ({context}) => { // Wait for the on-install welcome.html tab to load, which becomes the foreground tab - const welcome = await context.waitForEvent('page'); - await welcome.close(); // Close the welcome tab so our main tab becomes the foreground tab -- otherwise, the screenshot can hang + // Use a promise race to avoid hanging if the welcome page doesn't appear + try { + const welcome = await Promise.race([ + context.waitForEvent('page'), + new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000)) + ]); + await welcome.close(); // Close the welcome tab so our main tab becomes the foreground tab -- otherwise, the screenshot can hang + } catch (e) { + // If welcome page doesn't appear or already appeared, that's okay + console.log('Welcome page handling:', e.message); + } }); test('welcome', async ({page, extensionId}) => { @@ -34,6 +43,7 @@ test('welcome', async ({page, extensionId}) => { await expect(page.getByText('Welcome to Yomitan!')).toBeVisible(); // Take a screenshot of the welcome page + await page.bringToFront(); await expect.soft(page).toHaveScreenshot('welcome-page.png'); }); test.describe('settings', () => { @@ -48,6 +58,7 @@ test.describe('settings', () => { const storage_locator = page.locator('.storage-use-finite >> xpath=..'); // Take a simple screenshot of the settings page + await page.bringToFront(); await expect.soft(page).toHaveScreenshot('settings-fresh.png', {mask: [storage_locator]}); // Load in jmdict_english.zip @@ -56,6 +67,7 @@ test.describe('settings', () => { await expect(page.locator('id=dictionaries')).toHaveText('Dictionaries (1 installed, 1 enabled)', {timeout: 5 * 60 * 1000}); // Take a screenshot of the settings page with jmdict loaded + await page.bringToFront(); await expect.soft(page).toHaveScreenshot('settings-jmdict-loaded.png', {mask: [storage_locator]}); }); test('remote load and delete of jmdict_swedish', async ({page, extensionId}) => { @@ -99,6 +111,7 @@ test.describe('settings', () => { const storage_locator = page.locator('.storage-use-finite >> xpath=..'); // Take a full page screenshot of the settings page with advanced settings enabled + await page.bringToFront(); await expect.soft(page).toHaveScreenshot('settings-fresh-full-advanced.png', { fullPage: true, mask: [storage_locator],