Skip to content

Commit

Permalink
feat(testing): add playwright configuration generator
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Jul 12, 2023
1 parent 77bb4b7 commit 367dce3
Show file tree
Hide file tree
Showing 12 changed files with 308 additions and 149 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ commands:
command: |
sudo apt-get update
sudo apt-get install -y ca-certificates lsof
npx playwright install --with-deps
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run-pnpm-install:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/e2e-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ jobs:
if: steps.cache-cypress.outputs.cache-hit != 'true'
run: npx cypress install

- name: Cache Playwright
id: cache-playwright
uses: actions/cache@v3
with:
lookup-only: true
path: '${{ github.workspace }}/.cache/ms-playwright'
key: ${{ runner.os }}-playwright

- name: Install Playwright Browsers
if: steps.cache-playwright.outputs.cache-hit != 'true'
run: npx playwright install --with-deps

e2e:
needs: preinstall
permissions:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/e2e-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ jobs:
if: steps.cache-cypress.outputs.cache-hit != 'true'
run: npx cypress install

- name: Cache Playwright
id: cache-playwright
uses: actions/cache@v3
with:
lookup-only: true
path: '${{ github.workspace }}/.cache/ms-playwright'
key: ${{ runner.os }}-playwright

- name: Install Playwright Browsers
if: steps.cache-playwright.outputs.cache-hit != 'true'
run: npx playwright install --with-deps

e2e:
needs: preinstall
permissions:
Expand Down
163 changes: 15 additions & 148 deletions e2e/playwright/src/playwright.test.ts
Original file line number Diff line number Diff line change
@@ -1,171 +1,38 @@
import {
cleanupProject,
newProject,
uniq,
createFile,
runCLI,
packageInstall,
runCommand,
} from '@nx/e2e/utils';
import { cleanupProject, newProject, uniq, runCLI } from '@nx/e2e/utils';

const TEN_MINS_MS = 600_000;
describe('Playwright E2E Test runner', () => {
beforeAll(() => {
newProject({ name: uniq('playwright') });
packageInstall('@playwright/test', undefined, '^1.30.0', 'dev');
runCommand('npx playwright install --with-deps');
});

afterAll(() => cleanupProject());

it(
'should test example app',
() => {
//TODO: remove when generators are setup.Need to have basic workspace deps setup
runCLI(`g @nx/js:init`);
addSampleProject();
runCLI(`g @nx/js:lib demo-e2e --unitTestRunner none --bundler none`);
runCLI(`g @nx/playwright:configuration --project demo-e2e`);

// NOTE: playwright throws errors if it detects running inside jest process. tmp remove and restore the env var for playwright to run
const results = runCLI(`e2e demo-e2e`);
expect(results).toContain('6 passed');
expect(results).toContain('Successfully ran target e2e for project');
},
TEN_MINS_MS
);
});

// TODO: remove this when there are project generators
function addSampleProject() {
createFile(
'apps/demo-e2e/src/example.spec.ts',
`
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});
test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Click the get started link.
await page.getByRole('link', { name: 'Get started' }).click();

// Expects the URL to contain intro.
await expect(page).toHaveURL(/.*intro/);
});
`
);
createFile(
'apps/demo-e2e/playwright.config.ts',
`
import { defineConfig, devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './src',
outputDir: '../../dist/playwright/apps/demo-e2e/output',
/* 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',
{
outputFolder:
'../../dist/playwright/apps/demo-e2e/playwright-report',
},
],
],
/* 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'] },
},
it(
'should test example app with js',
() => {
runCLI(
`g @nx/js:lib demo-js-e2e --unitTestRunner none --bundler none --js`
);
runCLI(`g @nx/playwright:configuration --project demo-js-e2e --js`);

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
const results = runCLI(`e2e demo-js-e2e`);
expect(results).toContain('6 passed');
expect(results).toContain('Successfully ran target e2e for project');
},
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});
`
);
createFile(
'apps/demo-e2e/project.json',
JSON.stringify(
{
name: 'demo-e2e',
root: 'apps/demo-e2e',
sourceRoot: 'apps/demo-e2e/src',
targets: {
e2e: {
executor: '@nx/playwright:playwright',
options: {},
},
},
},
null,
2
)
TEN_MINS_MS
);
}
});
18 changes: 18 additions & 0 deletions packages/playwright/generators.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Nx Playwright",
"version": "0.1",
"schematics": {
"configuration": {
"factory": "./src/generators/configuration/generator#configurationSchematic",
"schema": "./src/generators/configuration/schema.json",
"description": "Add Nx Playwright configuration to your project"
}
},
"generators": {
"configuration": {
"factory": "./src/generators/configuration/generator",
"schema": "./src/generators/configuration/schema.json",
"description": "Add Nx Playwright configuration to your project"
}
}
}
3 changes: 2 additions & 1 deletion packages/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"optional": true
}
},
"executors": "./executors.json"
"executors": "./executors.json",
"generators": "./generators.json"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { test, expect } from '@playwright/test';

test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');

// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});

test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');

// Click the get started link.
await page.getByRole('link', { name: 'Get started' }).click();

// Expects the URL to contain intro.
await expect(page).toHaveURL(/.*intro/);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { defineConfig, devices } from '@playwright/test';

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './<%= directory %>',
/* 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',
{
outputFolder:
'<%= offsetFromRoot %>/dist/playwright/<%= projectRoot %>/playwright-report',
},
],
],
/* 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'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});
Loading

0 comments on commit 367dce3

Please sign in to comment.