Skip to content

Commit

Permalink
feat(7): Angular dev server
Browse files Browse the repository at this point in the history
  • Loading branch information
jfgreffier committed Oct 20, 2024
1 parent bc31793 commit eed185d
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 12 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,42 @@ ng e2e --ui

For a list of accepted arguments, use `ng e2e --help`. If you need more options and control on the CLI, the best solution is to use `npx playwright test` directly.

### Run an Angular dev server
If a `devServerTarget` option is specified, the builder will launch an Angular server and will set `PLAYWRIGHT_TEST_BASE_URL` environment variable automatically.

```json title="angular.json"
"e2e": {
"builder": "playwright-ng-schematics:playwright",
"options": {
"devServerTarget": "my-app:serve",
"ui": true
},
"configurations": {
"production": {
"devServerTarget": "my-app:serve:production"
}
}
}
```

You still can make use of Playwright's `baseURL` option and mix it with `PLAYWRIGHT_TEST_BASE_URL` env variable.
The example below has projects using `PLAYWRIGHT_TEST_BASE_URL` (set by `devServerTarget`) or other base URL.

```ts title="playwright.config.ts"
// ...
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], baseURL: process.env['PLAYWRIGHT_TEST_BASE_URL'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'], baseURL: 'http://example.com' },
},
]
```

## Create a test file

Create a new empty test
Expand Down
43 changes: 40 additions & 3 deletions src/builders/playwright/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import { spawn } from 'node:child_process';
import {
type BuilderContext,
type BuilderOutput,
type BuilderRun,
createBuilder,
targetFromTargetString,
} from '@angular-devkit/architect';
import type { JsonObject } from '@angular-devkit/core';

interface Options extends JsonObject {
devServerTarget: string;
debug: boolean;
trace: string;
'update-snapshots': boolean;
Expand All @@ -30,12 +33,33 @@ function buildArgs(options: Options) {
return args;
}

async function startPlaywrightTest(options: Options) {
async function startDevServer(
context: BuilderContext,
devServerTarget: string,
): Promise<BuilderRun> {
const target = targetFromTargetString(devServerTarget);
const server = await context.scheduleTarget(target, {});

return server;
}

async function startPlaywrightTest(options: Options, baseURL: string) {
// PLAYWRIGHT_TEST_BASE_URL is actually a non-documented env variable used
// by Playwright Test.
// Its usage in playwright.config.ts is to clarify that it can be overriden.
let env = {};
if (baseURL) {
env = {
PLAYWRIGHT_TEST_BASE_URL: baseURL,
};
}

return new Promise((resolve, reject) => {
const childPorcess = spawn('npx playwright test', buildArgs(options), {
cwd: process.cwd(),
stdio: 'inherit',
shell: true,
env,
});

childPorcess.on('exit', (exitCode) => {
Expand All @@ -49,13 +73,26 @@ async function startPlaywrightTest(options: Options) {

async function runE2E(
options: Options,
_context: BuilderContext,
context: BuilderContext,
): Promise<BuilderOutput> {
let server: BuilderRun | undefined = undefined;
let baseURL = '';

try {
await startPlaywrightTest(options);
if (options.devServerTarget) {
server = await startDevServer(context, options.devServerTarget);
const result = await server.result;
baseURL = result.baseUrl;
}

await startPlaywrightTest(options, baseURL);
return { success: true };
} catch (error) {
return { success: false };
} finally {
if (server) {
server.stop();
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/builders/playwright/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"description": "Playwright builder options",
"type": "object",
"properties": {
"devServerTarget": {
"description": "Dev server target to run tests against",
"type": "string"
},
"debug": {
"description": "Run tests with Playwright Inspector",
"type": "boolean"
Expand Down
10 changes: 1 addition & 9 deletions src/schematics/ng-add/files/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default defineConfig({
/* 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://localhost:4200',
baseURL: process.env['PLAYWRIGHT_TEST_BASE_URL'] ?? 'http://localhost:4200',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
Expand Down Expand Up @@ -67,12 +67,4 @@ export default defineConfig({
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run start',
url: 'http://localhost:4200',
reuseExistingServer: !process.env['CI'],
stdout: 'pipe',
},
});
8 changes: 8 additions & 0 deletions src/schematics/ng-add/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ function updateAngular(tree: Tree, context: SchematicContext) {
for (const projectName of Object.keys(json.projects)) {
json.projects[projectName].architect.e2e = {
builder: 'playwright-ng-schematics:playwright',
options: {
devServerTarget: `${projectName}:serve`,
},
configurations: {
production: {
devServerTarget: `${projectName}:serve:production`,
},
},
};
}
tree.overwrite('angular.json', JSON.stringify(json, null, 2));
Expand Down

0 comments on commit eed185d

Please sign in to comment.