Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/nxPublic

Commite5e561d

Browse files
authored
feat(testing): add playwright configuration generator (#18013)
1 parentd489de5 commite5e561d

File tree

14 files changed

+353
-145
lines changed

14 files changed

+353
-145
lines changed

‎e2e/playwright/src/playwright.test.ts

Lines changed: 17 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -2,170 +2,45 @@ import {
22
cleanupProject,
33
newProject,
44
uniq,
5-
createFile,
65
runCLI,
7-
packageInstall,
8-
runCommand,
6+
ensurePlaywrightBrowsersInstallation,
97
}from'@nx/e2e/utils';
108

119
constTEN_MINS_MS=600_000;
1210
describe('Playwright E2E Test runner',()=>{
1311
beforeAll(()=>{
1412
newProject({name:uniq('playwright')});
15-
packageInstall('@playwright/test',undefined,'^1.30.0','dev');
16-
runCommand('npx playwright install --with-deps');
1713
});
1814

1915
afterAll(()=>cleanupProject());
2016

2117
it(
2218
'should test example app',
2319
()=>{
24-
//TODO: remove when generators are setup.Need to have basic workspace deps setup
25-
runCLI(`g @nx/js:init`);
26-
addSampleProject();
20+
runCLI(`g @nx/js:lib demo-e2e --unitTestRunner none --bundler none`);
21+
runCLI(`g @nx/playwright:configuration --project demo-e2e`);
22+
ensurePlaywrightBrowsersInstallation();
2723

28-
// NOTE: playwright throws errors if it detects running inside jest process. tmp remove and restore the env var for playwright to run
2924
constresults=runCLI(`e2e demo-e2e`);
3025
expect(results).toContain('6 passed');
3126
expect(results).toContain('Successfully ran target e2e for project');
3227
},
3328
TEN_MINS_MS
3429
);
35-
});
36-
37-
// TODO: remove this when there are project generators
38-
functionaddSampleProject(){
39-
createFile(
40-
'apps/demo-e2e/src/example.spec.ts',
41-
`
42-
import { test, expect } from '@playwright/test';
43-
44-
test('has title', async ({ page }) => {
45-
await page.goto('https://playwright.dev/');
46-
47-
// Expect a title "to contain" a substring.
48-
await expect(page).toHaveTitle(/Playwright/);
49-
});
50-
51-
test('get started link', async ({ page }) => {
52-
await page.goto('https://playwright.dev/');
53-
54-
// Click the get started link.
55-
await page.getByRole('link', { name: 'Get started' }).click();
5630

57-
// Expects the URL to contain intro.
58-
await expect(page).toHaveURL(/.*intro/);
59-
});
60-
`
61-
);
62-
createFile(
63-
'apps/demo-e2e/playwright.config.ts',
64-
`
65-
import { defineConfig, devices } from '@playwright/test';
66-
67-
/**
68-
* Read environment variables from file.
69-
* https://github.com/motdotla/dotenv
70-
*/
71-
// require('dotenv').config();
72-
73-
/**
74-
* See https://playwright.dev/docs/test-configuration.
75-
*/
76-
export default defineConfig({
77-
testDir: './src',
78-
outputDir: '../../dist/playwright/apps/demo-e2e/output',
79-
/* Run tests in files in parallel */
80-
fullyParallel: true,
81-
/* Fail the build on CI if you accidentally left test.only in the source code. */
82-
forbidOnly: !!process.env.CI,
83-
/* Retry on CI only */
84-
retries: process.env.CI ? 2 : 0,
85-
/* Opt out of parallel tests on CI. */
86-
workers: process.env.CI ? 1 : undefined,
87-
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
88-
reporter: [
89-
[
90-
'html',
91-
{
92-
outputFolder:
93-
'../../dist/playwright/apps/demo-e2e/playwright-report',
94-
},
95-
],
96-
],
97-
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
98-
use: {
99-
/* Base URL to use in actions like await page.goto('/'). */
100-
// baseURL: 'http://127.0.0.1:3000',
101-
102-
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
103-
trace: 'on-first-retry',
104-
},
105-
106-
/* Configure projects for major browsers */
107-
projects: [
108-
{
109-
name: 'chromium',
110-
use: { ...devices['Desktop Chrome'] },
111-
},
112-
113-
{
114-
name: 'firefox',
115-
use: { ...devices['Desktop Firefox'] },
116-
},
31+
it(
32+
'should test example app with js',
33+
()=>{
34+
runCLI(
35+
`g @nx/js:lib demo-js-e2e --unitTestRunner none --bundler none --js`
36+
);
37+
runCLI(`g @nx/playwright:configuration --project demo-js-e2e --js`);
38+
ensurePlaywrightBrowsersInstallation();
11739

118-
{
119-
name: 'webkit',
120-
use: { ...devices['Desktop Safari'] },
40+
constresults=runCLI(`e2e demo-js-e2e`);
41+
expect(results).toContain('6 passed');
42+
expect(results).toContain('Successfully ran target e2e for project');
12143
},
122-
123-
/* Test against mobile viewports. */
124-
// {
125-
// name: 'Mobile Chrome',
126-
// use: { ...devices['Pixel 5'] },
127-
// },
128-
// {
129-
// name: 'Mobile Safari',
130-
// use: { ...devices['iPhone 12'] },
131-
// },
132-
133-
/* Test against branded browsers. */
134-
// {
135-
// name: 'Microsoft Edge',
136-
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
137-
// },
138-
// {
139-
// name: 'Google Chrome',
140-
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
141-
// },
142-
],
143-
144-
/* Run your local dev server before starting the tests */
145-
// webServer: {
146-
// command: 'npm run start',
147-
// url: 'http://127.0.0.1:3000',
148-
// reuseExistingServer: !process.env.CI,
149-
// },
150-
});
151-
`
152-
);
153-
createFile(
154-
'apps/demo-e2e/project.json',
155-
JSON.stringify(
156-
{
157-
name:'demo-e2e',
158-
root:'apps/demo-e2e',
159-
sourceRoot:'apps/demo-e2e/src',
160-
targets:{
161-
e2e:{
162-
executor:'@nx/playwright:playwright',
163-
options:{},
164-
},
165-
},
166-
},
167-
null,
168-
2
169-
)
44+
TEN_MINS_MS
17045
);
171-
}
46+
});

‎e2e/utils/get-env-info.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,17 @@ export function ensureCypressInstallation() {
111111
}
112112
}
113113

114+
exportfunctionensurePlaywrightBrowsersInstallation(){
115+
execSync('npx playwright install --with-deps --force',{
116+
stdio:isVerbose() ?'inherit' :'pipe',
117+
encoding:'utf-8',
118+
cwd:tmpProjPath(),
119+
});
120+
e2eConsoleLogger(
121+
`Playwright browsers${execSync('npx playwright --version')} installed.`
122+
);
123+
}
124+
114125
exportfunctiongetStrippedEnvironmentVariables(){
115126
returnObject.fromEntries(
116127
Object.entries(process.env).filter(([key,value])=>{

‎packages/playwright/.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"rules": {}
1616
},
1717
{
18-
"files": ["./package.json","./executors.json"],
18+
"files": ["./package.json","./executors.json","./generators.json"],
1919
"parser":"jsonc-eslint-parser",
2020
"rules": {
2121
"@nx/nx-plugin-checks":"error"

‎packages/playwright/generators.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name":"Nx Playwright",
3+
"version":"0.1",
4+
"schematics": {
5+
"configuration": {
6+
"factory":"./src/generators/configuration/configuration#configurationSchematic",
7+
"schema":"./src/generators/configuration/schema.json",
8+
"description":"Add Nx Playwright configuration to your project"
9+
},
10+
"init": {
11+
"factory":"./src/generators/init/init#initSchematic",
12+
"schema":"./src/generators/init/schema.json",
13+
"description":"Initializes a Playwright project in the current workspace"
14+
}
15+
},
16+
"generators": {
17+
"configuration": {
18+
"factory":"./src/generators/configuration/configuration",
19+
"schema":"./src/generators/configuration/schema.json",
20+
"description":"Add Nx Playwright configuration to your project"
21+
},
22+
"init": {
23+
"factory":"./src/generators/init/init",
24+
"schema":"./src/generators/init/schema.json",
25+
"description":"Initializes a Playwright project in the current workspace"
26+
}
27+
}
28+
}

‎packages/playwright/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@
3232
"@nx/devkit":"file:../devkit"
3333
},
3434
"peerDependencies": {
35-
"@playwright/test":"^1.30.0"
35+
"@playwright/test":"^1.36.0"
3636
},
3737
"peerDependenciesMeta": {
3838
"@playwright/test": {
3939
"optional":true
4040
}
4141
},
42-
"executors":"./executors.json"
42+
"executors":"./executors.json",
43+
"generators":"./generators.json"
4344
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import{
2+
convertNxGenerator,
3+
formatFiles,
4+
generateFiles,
5+
offsetFromRoot,
6+
readNxJson,
7+
readProjectConfiguration,
8+
toJS,
9+
Tree,
10+
updateNxJson,
11+
updateProjectConfiguration,
12+
}from'@nx/devkit';
13+
import*aspathfrom'path';
14+
import{ConfigurationGeneratorSchema}from'./schema';
15+
importinitGeneratorfrom'../init/init';
16+
17+
exportasyncfunctionconfigurationGenerator(
18+
tree:Tree,
19+
options:ConfigurationGeneratorSchema
20+
){
21+
constprojectConfig=readProjectConfiguration(tree,options.project);
22+
generateFiles(tree,path.join(__dirname,'files'),projectConfig.root,{
23+
offsetFromRoot:offsetFromRoot(projectConfig.root),
24+
projectRoot:projectConfig.root,
25+
...options,
26+
});
27+
28+
addE2eTarget(tree,options);
29+
setupE2ETargetDefaults(tree);
30+
31+
if(options.js){
32+
toJS(tree);
33+
}
34+
if(!options.skipFormat){
35+
awaitformatFiles(tree);
36+
}
37+
38+
returninitGenerator(tree,{
39+
skipFormat:true,
40+
skipPackageJson:options.skipPackageJson,
41+
});
42+
}
43+
44+
functionsetupE2ETargetDefaults(tree:Tree){
45+
constnxJson=readNxJson(tree);
46+
47+
if(!nxJson.namedInputs){
48+
return;
49+
}
50+
51+
// E2e targets depend on all their project's sources + production sources of dependencies
52+
nxJson.targetDefaults??={};
53+
54+
constproductionFileSet=!!nxJson.namedInputs?.production;
55+
nxJson.targetDefaults.e2e??={};
56+
nxJson.targetDefaults.e2e.inputs??=[
57+
'default',
58+
productionFileSet ?'^production' :'^default',
59+
];
60+
61+
updateNxJson(tree,nxJson);
62+
}
63+
64+
functionaddE2eTarget(tree:Tree,options:ConfigurationGeneratorSchema){
65+
constprojectConfig=readProjectConfiguration(tree,options.project);
66+
if(projectConfig?.targets?.e2e){
67+
thrownewError(`Project${options.project} already has an e2e target.
68+
Rename or remove the existing e2e target.`);
69+
}
70+
projectConfig.targets.e2e={
71+
executor:'@nx/playwright:playwright',
72+
options:{},
73+
};
74+
updateProjectConfiguration(tree,options.project,projectConfig);
75+
}
76+
77+
exportdefaultconfigurationGenerator;
78+
exportconstconfigurationSchematic=convertNxGenerator(
79+
configurationGenerator
80+
);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test('has title', async ({ page }) => {
4+
await page.goto('https://playwright.dev/');
5+
6+
// Expect a title "to contain" a substring.
7+
await expect(page).toHaveTitle(/Playwright/);
8+
});
9+
10+
test('get started link', async ({ page }) => {
11+
await page.goto('https://playwright.dev/');
12+
13+
// Click the get started link.
14+
await page.getByRole('link', { name: 'Get started' }).click();
15+
16+
// Expects the URL to contain intro.
17+
await expect(page).toHaveURL(/.*intro/);
18+
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp