From 19998387b7f97a0b627d85184207c934d0a498ed Mon Sep 17 00:00:00 2001 From: likimmy <141841537+likimmy@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:50:31 -0500 Subject: [PATCH] Implement playwright acceptance tests for vertical full page map (#1155) * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map * Implement playwright acceptance tests for vertical full page map --- .github/workflows/acceptance_browserstack.yml | 39 ----- .github/workflows/playwright.yml | 31 ++++ .gitignore | 6 +- e2e/vertical-full-page-map.spec.ts | 135 ++++++++++++++++++ package-lock.json | 135 +++++++++++++++--- package.json | 2 + playwright.config.ts | 48 +++++++ 7 files changed, 335 insertions(+), 61 deletions(-) delete mode 100644 .github/workflows/acceptance_browserstack.yml create mode 100644 .github/workflows/playwright.yml create mode 100644 e2e/vertical-full-page-map.spec.ts create mode 100644 playwright.config.ts diff --git a/.github/workflows/acceptance_browserstack.yml b/.github/workflows/acceptance_browserstack.yml deleted file mode 100644 index 667ea4f82..000000000 --- a/.github/workflows/acceptance_browserstack.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Browserstack Acceptance Tests - -on: - push: - branches-ignore: dev/* - -jobs: - browserstack-safari-acceptance-tests: - name: Safari Acceptance Tests (Browserstack) - runs-on: ubuntu-latest - env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 14 - - run: npm ci - - run: npm run setup-test-site - - run: npm run build-test-site - - name: Run Acceptance Tests - run: ./.github/run_browserstack_acceptance.sh browserstack:safari - browserstack-firefox-acceptance-tests: - name: Firefox Acceptance Tests (Browserstack) - runs-on: ubuntu-latest - env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 14 - - run: npm ci - - run: npm run setup-test-site - - run: npm run build-test-site - - name: Run Acceptance Tests - run: ./.github/run_browserstack_acceptance.sh browserstack:firefox diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 000000000..35984e445 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,31 @@ +name: Playwright Tests + +on: + push: + branches-ignore: dev/* + +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 14 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Setup test site + run: npm run setup-test-site + - name: Build test site + run: npm run build-test-site + - 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 b844ea603..0a0c46f32 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,8 @@ static/node_modules/ static/dist/ node_modules **/.DS_Store -.idea/ \ No newline at end of file +.idea/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/e2e/vertical-full-page-map.spec.ts b/e2e/vertical-full-page-map.spec.ts new file mode 100644 index 000000000..90a087840 --- /dev/null +++ b/e2e/vertical-full-page-map.spec.ts @@ -0,0 +1,135 @@ +import { test, expect } from '@playwright/test'; + +async function waitForResultsToLoad(page) { + const result = page.locator('#js-answersVerticalResults div').nth(0); + await expect(result).toBeAttached(); +} + +test.describe('full page map test suite', () => { + test.beforeEach(async ({page}) => { + await page.goto('http://localhost:5042/locations_full_page_map'); + }); + + test('can search and get results', async ({ page }) => { + await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('queryTrigger')); + const prevResultsCount = await page.locator('.yxt-VerticalResultsCount-total').textContent(); + + await page.getByPlaceholder('Search for locations').fill('virginia'); + await page.getByPlaceholder('Search for locations').press('Enter'); + await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('input=virginia')); + const resultsCount = await page.locator('.yxt-VerticalResultsCount-total').textContent(); + + expect(prevResultsCount).not.toBe(resultsCount); + }); + + test('clicking on a pin focuses on a result card', async ({ page }) => { + await expect(page.locator('.yxt-Card--pinFocused')).not.toBeAttached(); + await page.getByRole('button', { name: 'Result number 13' }).click(); + await expect(page.locator('.yxt-Card--pinFocused')).toBeAttached(); + }); + + test('search when map moves works', async ({ page }) => { + await page.getByPlaceholder('Search for locations').fill('virginia'); + await page.getByPlaceholder('Search for locations').press('Enter'); + await waitForResultsToLoad(page); + const map = page.locator('.mapboxgl-canvas'); + await map.dragTo(map, { + sourcePosition: { x: 788, y: 345}, + targetPosition: { x: 1011, y: 225}, + }) + const response = await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('radius')); + expect(response.status()).toBe(200); + }); + + test('search this area button works', async ({ page }) => { + await page.getByLabel('Map controls').getByText('Search When Map Moves').click(); + await page.getByPlaceholder('Search for locations').fill('virginia'); + await page.getByPlaceholder('Search for locations').press('Enter'); + await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && !resp.url().includes('radius')); + await page.locator('div').filter({ hasText: /^Search This Area$/ }).nth(1).click(); + const response = await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('radius')); + expect(response.status()).toBe(200); + }); + + test('default initial search works and is enabled by default', async ({ page }) => { + const response = await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('queryTrigger')); + expect(response.status()).toBe(200); + }); + + test('empty search works', async ({ page }) => { + await page.getByPlaceholder('Search for locations').press('Enter'); + const response = await page.waitForResponse(resp => + resp.url().includes('https:\/\/prod-cdn\.us\.yextapis\.com\/v2\/accounts\/me\/search\/vertical\/query') + && resp.url().includes('input=&')); + expect(response.status()).toBe(200); + }) + + test('pagination works', async ({ page }) => { + const resultsCount = page.locator('#js-answersVerticalResultsCount'); + await expect(resultsCount).toHaveText(/20/); + await page.getByLabel('Go to the next page of results').click(); + await expect(resultsCount).toHaveText(/21/); + }); + + test('pagination scrolls the results to the top', async ({ page }) => { + await page.evaluate(() => window.scrollTo(0, document.documentElement.scrollHeight)); + + const scrollOffsetBeforePagination = await page.evaluate(() => {return window.scrollY}); + expect(scrollOffsetBeforePagination).not.toBe(0); + + await page.getByLabel('Go to the next page of results').click(); + await waitForResultsToLoad(page); + + const scrollOffsetAfterPagination = await page.evaluate(() => {return window.scrollY}); + expect(scrollOffsetAfterPagination).toBe(0); + }); + +}); + +test.describe('full page map with filters test suite', () => { + test.beforeEach(async ({page}) => { + await page.goto('http://localhost:5042/locations_full_page_map_with_filters'); + }); + + test('clicking on a pin closes the filter view', async ({ page }) => { + await page.getByRole('button', { name: 'filter results' }).click(); + const filters = page.locator('#js-answersFacets'); + await expect(filters).toBeVisible(); + await page.getByRole('button', { name: 'Result number 7' }).click(); + await expect(filters).not.toBeVisible(); + }); + + test('clicking on a cluster causes the map to zoom in and new search is ran', async ({ page }) => { + await page.getByPlaceholder('Search for locations').fill('virginia'); + await page.getByPlaceholder('Search for locations').press('Enter'); + await page.waitForResponse(resp => resp.url().includes('https://prod-cdn.us.yextapis.com/v2/accounts/me/search/vertical/query') + && resp.url().includes('input=virginia') + && !resp.url().includes('filters')); + + await waitForResultsToLoad(page); + + const originalCount = await page.locator('.yxt-Card').count(); + + await page.getByRole('button', { name: 'Cluster of 2 results' }).click(); + await page.waitForResponse(resp => resp.url().includes('https://prod-cdn.us.yextapis.com/v2/accounts/me/search/vertical/query') + && resp.url().includes('input=virginia') + && resp.url().includes('filters')); + + await waitForResultsToLoad(page); + + const countAfterSelectingCluster = await page.locator('.yxt-Card').count(); + expect(originalCount).toBeGreaterThan(countAfterSelectingCluster); + }); +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d2252f3d3..d8f6e7040 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "@babel/preset-env": "^7.9.6", "@percy/cli": "^1.0.0-beta.67", "@percy/puppeteer": "^2.0.0", + "@playwright/test": "^1.39.0", "@types/jest": "^26.0.19", + "@types/node": "^20.9.0", "@yext/cta-formatter": "^1.0.0", "babel-jest": "^25.5.1", "comment-json": "^4.1.1", @@ -3693,6 +3695,21 @@ "node": ">=12" } }, + "node_modules/@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "dependencies": { + "playwright": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -3923,10 +3940,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "13.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", - "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", - "dev": true + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -5313,9 +5333,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001328", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001328.tgz", - "integrity": "sha512-Ue55jHkR/s4r00FLNiX+hGMMuwml/QGqqzVeMQ5thUewznU2EdULFvI3JR7JJid6OrjJNfFvHY2G2dIjmRaDDQ==", + "version": "1.0.30001563", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", + "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", "dev": true, "funding": [ { @@ -5325,6 +5345,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -7336,10 +7360,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -11097,6 +11120,36 @@ "node": ">=8" } }, + "node_modules/playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "dependencies": { + "playwright-core": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -15347,6 +15400,12 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -18865,6 +18924,15 @@ "@percy/logger": "1.0.0-beta.63" } }, + "@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "requires": { + "playwright": "1.39.0" + } + }, "@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -19076,10 +19144,13 @@ "dev": true }, "@types/node": { - "version": "13.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", - "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", - "dev": true + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/normalize-package-data": { "version": "2.4.1", @@ -20167,9 +20238,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001328", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001328.tgz", - "integrity": "sha512-Ue55jHkR/s4r00FLNiX+hGMMuwml/QGqqzVeMQ5thUewznU2EdULFvI3JR7JJid6OrjJNfFvHY2G2dIjmRaDDQ==", + "version": "1.0.30001563", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", + "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", "dev": true }, "capture-exit": { @@ -21806,9 +21877,9 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -24794,6 +24865,22 @@ "find-up": "^4.0.0" } }, + "playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.39.0" + } + }, + "playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -28089,6 +28176,12 @@ } } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index e5263f31f..ec5b0cb0a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "@babel/preset-env": "^7.9.6", "@percy/cli": "^1.0.0-beta.67", "@percy/puppeteer": "^2.0.0", + "@playwright/test": "^1.39.0", "@types/jest": "^26.0.19", + "@types/node": "^20.9.0", "@yext/cta-formatter": "^1.0.0", "babel-jest": "^25.5.1", "comment-json": "^4.1.1", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 000000000..d64f9b3dc --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,48 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: './e2e', + timeout: 10000, + /* 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:5042', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + video: 'retain-on-failure', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ...(process.env.CI ? [] : [{ + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }]), + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run serve-test-site', + url: 'http://127.0.0.1:5042', + reuseExistingServer: true, + }, +});