diff --git a/.eslintrc.js b/.eslintrc.js index afceded6..b94604ec 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,7 +39,7 @@ module.exports = { jest: true, es2021: true, }, - ignorePatterns: ["test", "dist", "build", "public", "/**/node_modules/*", ".eslintrc.js", "vite.config.ts", "vite-env.d.ts", "postcss.config.js", "tailwind.config.js", "vitest.config.ts"], + ignorePatterns: ["test", "dist", "build", "public", "/**/node_modules/*", ".eslintrc.js", "vite.config.ts", "vite-env.d.ts", "postcss.config.js", "tailwind.config.js", "vitest.config.ts", "playwright.config.ts", "e2e"], rules: { "indent": "off", "@typescript-eslint/indent": "error", @@ -449,4 +449,4 @@ module.exports = { "@typescript-eslint/parser": [".js", ".jsx", ".ts", ".tsx"], }, }, -}; \ No newline at end of file +}; diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..63caa3b2 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + push: + branches: [ main, beta ] + pull_request: + branches: [ main, beta ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 7d1e40ef..d3a95ab6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ dist-ssr *.njsproj *.sln *.sw? +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/e2e/open-popup.spec.ts b/e2e/open-popup.spec.ts new file mode 100644 index 00000000..1e5d2a8b --- /dev/null +++ b/e2e/open-popup.spec.ts @@ -0,0 +1,6 @@ +import { test, expect } from './popupFixture'; + +test('popup page', async ({ page, extensionId }) => { + await page.goto(`chrome-extension://${extensionId}/index.html`); + expect(page.locator('body')).toBeTruthy(); +}); diff --git a/e2e/popupFixture.ts b/e2e/popupFixture.ts new file mode 100644 index 00000000..281ad137 --- /dev/null +++ b/e2e/popupFixture.ts @@ -0,0 +1,30 @@ +import { test as base, chromium, type BrowserContext } from "@playwright/test"; +import path from "path"; + +export const test = base.extend<{ + context: BrowserContext; + extensionId: string; +}>({ + context: async ({}, use) => { + const pathToExtension = path.join(__dirname, "../dist"); + const context = await chromium.launchPersistentContext("", { + headless: false, + args: [ + `--headless=new`, + `--disable-extensions-except=${pathToExtension}`, + `--load-extension=${pathToExtension}`, + ], + }); + await use(context); + await context.close(); + }, + extensionId: async ({ context }, use) => { + let [background] = context.serviceWorkers(); + if (!background) background = await context.waitForEvent("serviceworker"); + + const extensionId = background.url().split("/")[2]; + await use(extensionId); + }, +}); + +export const expect = test.expect; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 896dfc54..a7dc8c75 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -22,6 +22,7 @@ }, "devDependencies": { "@crxjs/vite-plugin": "^1.0.14", + "@playwright/test": "^1.37.1", "@types/chrome": "^0.0.237", "@types/node": "^20.1.4", "@types/node-emoji": "^1.8.2", @@ -1100,6 +1101,25 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", + "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "playwright-core": "1.37.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, "node_modules/@rollup/pluginutils": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", @@ -6503,6 +6523,18 @@ "pathe": "^1.1.0" } }, + "node_modules/playwright-core": { + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", + "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/postcss": { "version": "8.4.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", diff --git a/package.json b/package.json index 3a8be568..cc180dd0 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "lint": "eslint . --report-unused-disable-directives", "format": "npm run lint -- --fix", "test": "vitest run", + "e2e": "npx playwright test", "coverage": "vitest run --coverage" }, "dependencies": { @@ -29,6 +30,7 @@ }, "devDependencies": { "@crxjs/vite-plugin": "^1.0.14", + "@playwright/test": "^1.37.1", "@types/chrome": "^0.0.237", "@types/node": "^20.1.4", "@types/node-emoji": "^1.8.2", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..82f08d6d --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,45 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './e2e', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run dev', + url: 'http://127.0.0.1:3000', + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts index efd98065..f31878df 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -4,5 +4,6 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { environment: "jsdom", + include: ["test/**/*.test.ts"], }, -}); \ No newline at end of file +});