feat(testing): add metadata to playwright targets (#22768)

This commit is contained in:
Craigory Coppola 2024-04-10 18:12:44 -04:00 committed by GitHub
parent fd7cf38c20
commit c8f179d2d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 100 additions and 20 deletions

View File

@ -46,6 +46,13 @@ describe('@nx/playwright/plugin', () => {
expect(projects).toMatchInlineSnapshot(` expect(projects).toMatchInlineSnapshot(`
{ {
".": { ".": {
"metadata": {
"targetGroups": {
"E2E (CI)": [
"e2e-ci",
],
},
},
"root": ".", "root": ".",
"targets": { "targets": {
"e2e": { "e2e": {
@ -55,6 +62,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests",
"technologies": [
"playwright",
],
},
"options": { "options": {
"cwd": "{projectRoot}", "cwd": "{projectRoot}",
}, },
@ -70,6 +83,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests in CI",
"technologies": [
"playwright",
],
},
"outputs": [ "outputs": [
"{projectRoot}/test-results", "{projectRoot}/test-results",
], ],
@ -99,6 +118,13 @@ describe('@nx/playwright/plugin', () => {
expect(projects).toMatchInlineSnapshot(` expect(projects).toMatchInlineSnapshot(`
{ {
".": { ".": {
"metadata": {
"targetGroups": {
"E2E (CI)": [
"e2e-ci",
],
},
},
"root": ".", "root": ".",
"targets": { "targets": {
"e2e": { "e2e": {
@ -108,6 +134,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests",
"technologies": [
"playwright",
],
},
"options": { "options": {
"cwd": "{projectRoot}", "cwd": "{projectRoot}",
}, },
@ -126,6 +158,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests in CI",
"technologies": [
"playwright",
],
},
"outputs": [ "outputs": [
"{projectRoot}/playwright-report", "{projectRoot}/playwright-report",
"{projectRoot}/test-results/report.json", "{projectRoot}/test-results/report.json",
@ -164,6 +202,15 @@ describe('@nx/playwright/plugin', () => {
context context
); );
const { targets } = projects['.']; const { targets } = projects['.'];
expect(projects['.'].metadata.targetGroups).toMatchInlineSnapshot(`
{
"E2E (CI)": [
"e2e-ci--tests/run-me-2.spec.ts",
"e2e-ci--tests/run-me.spec.ts",
"e2e-ci",
],
}
`);
expect(targets['e2e-ci']).toMatchInlineSnapshot(` expect(targets['e2e-ci']).toMatchInlineSnapshot(`
{ {
"cache": true, "cache": true,
@ -184,6 +231,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests in CI",
"technologies": [
"playwright",
],
},
"outputs": [ "outputs": [
"{projectRoot}/test-results", "{projectRoot}/test-results",
], ],
@ -197,6 +250,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests in tests/run-me.spec.ts in CI",
"technologies": [
"playwright",
],
},
"options": { "options": {
"cwd": "{projectRoot}", "cwd": "{projectRoot}",
}, },
@ -213,6 +272,12 @@ describe('@nx/playwright/plugin', () => {
"default", "default",
"^production", "^production",
], ],
"metadata": {
"description": "Runs Playwright Tests in tests/run-me-2.spec.ts in CI",
"technologies": [
"playwright",
],
},
"options": { "options": {
"cwd": "{projectRoot}", "cwd": "{projectRoot}",
}, },

View File

@ -8,6 +8,7 @@ import {
detectPackageManager, detectPackageManager,
joinPathFragments, joinPathFragments,
normalizePath, normalizePath,
ProjectConfiguration,
readJsonFile, readJsonFile,
TargetConfiguration, TargetConfiguration,
writeJsonFile, writeJsonFile,
@ -36,21 +37,15 @@ const cachePath = join(projectGraphCacheDirectory, 'playwright.hash');
const targetsCache = existsSync(cachePath) ? readTargetsCache() : {}; const targetsCache = existsSync(cachePath) ? readTargetsCache() : {};
const calculatedTargets: Record< type PlaywrightTargets = Pick<ProjectConfiguration, 'targets' | 'metadata'>;
string,
Record<string, TargetConfiguration>
> = {};
function readTargetsCache(): Record< const calculatedTargets: Record<string, PlaywrightTargets> = {};
string,
Record<string, TargetConfiguration> function readTargetsCache(): Record<string, PlaywrightTargets> {
> {
return readJsonFile(cachePath); return readJsonFile(cachePath);
} }
function writeTargetsToCache( function writeTargetsToCache(targets: Record<string, PlaywrightTargets>) {
targets: Record<string, Record<string, TargetConfiguration>>
) {
writeJsonFile(cachePath, targets); writeJsonFile(cachePath, targets);
} }
@ -79,7 +74,7 @@ export const createNodes: CreateNodes<PlaywrightPluginOptions> = [
getLockFileName(detectPackageManager(context.workspaceRoot)), getLockFileName(detectPackageManager(context.workspaceRoot)),
]); ]);
const targets = const { targets, metadata } =
targetsCache[hash] ?? targetsCache[hash] ??
(await buildPlaywrightTargets( (await buildPlaywrightTargets(
configFilePath, configFilePath,
@ -88,13 +83,14 @@ export const createNodes: CreateNodes<PlaywrightPluginOptions> = [
context context
)); ));
calculatedTargets[hash] = targets; calculatedTargets[hash] = { targets, metadata };
return { return {
projects: { projects: {
[projectRoot]: { [projectRoot]: {
root: projectRoot, root: projectRoot,
targets, targets,
metadata,
}, },
}, },
}; };
@ -106,7 +102,7 @@ async function buildPlaywrightTargets(
projectRoot: string, projectRoot: string,
options: NormalizedOptions, options: NormalizedOptions,
context: CreateNodesContext context: CreateNodesContext
) { ): Promise<PlaywrightTargets> {
// Playwright forbids importing the `@playwright/test` module twice. This would affect running the tests, // Playwright forbids importing the `@playwright/test` module twice. This would affect running the tests,
// but we're just reading the config so let's delete the variable they are using to detect this. // but we're just reading the config so let's delete the variable they are using to detect this.
// See: https://github.com/microsoft/playwright/pull/11218/files // See: https://github.com/microsoft/playwright/pull/11218/files
@ -118,13 +114,18 @@ async function buildPlaywrightTargets(
const namedInputs = getNamedInputs(projectRoot, context); const namedInputs = getNamedInputs(projectRoot, context);
const targets: Record<string, TargetConfiguration<unknown>> = {}; const targets: ProjectConfiguration['targets'] = {};
let metadata: ProjectConfiguration['metadata'];
const baseTargetConfig: TargetConfiguration = { const baseTargetConfig: TargetConfiguration = {
command: 'playwright test', command: 'playwright test',
options: { options: {
cwd: '{projectRoot}', cwd: '{projectRoot}',
}, },
metadata: {
technologies: ['playwright'],
description: 'Runs Playwright Tests',
},
}; };
targets[options.targetName] = { targets[options.targetName] = {
@ -148,6 +149,10 @@ async function buildPlaywrightTargets(
outputs: getOutputs(projectRoot, playwrightConfig), outputs: getOutputs(projectRoot, playwrightConfig),
}; };
const groupName = 'E2E (CI)';
metadata = { targetGroups: { [groupName]: [] } };
const ciTargetGroup = metadata.targetGroups[groupName];
const testDir = playwrightConfig.testDir const testDir = playwrightConfig.testDir
? joinPathFragments(projectRoot, playwrightConfig.testDir) ? joinPathFragments(projectRoot, playwrightConfig.testDir)
: projectRoot; : projectRoot;
@ -158,13 +163,18 @@ async function buildPlaywrightTargets(
const dependsOn: TargetConfiguration['dependsOn'] = []; const dependsOn: TargetConfiguration['dependsOn'] = [];
forEachTestFile( forEachTestFile(
(testFile) => { (testFile) => {
const relativeToProjectRoot = normalizePath( const relativeSpecFilePath = normalizePath(
relative(projectRoot, testFile) relative(projectRoot, testFile)
); );
const targetName = `${options.ciTargetName}--${relativeToProjectRoot}`; const targetName = `${options.ciTargetName}--${relativeSpecFilePath}`;
ciTargetGroup.push(targetName);
targets[targetName] = { targets[targetName] = {
...ciBaseTargetConfig, ...ciBaseTargetConfig,
command: `${baseTargetConfig.command} ${relativeToProjectRoot}`, command: `${baseTargetConfig.command} ${relativeSpecFilePath}`,
metadata: {
technologies: ['playwright'],
description: `Runs Playwright Tests in ${relativeSpecFilePath} in CI`,
},
}; };
dependsOn.push({ dependsOn.push({
target: targetName, target: targetName,
@ -187,13 +197,18 @@ async function buildPlaywrightTargets(
inputs: ciBaseTargetConfig.inputs, inputs: ciBaseTargetConfig.inputs,
outputs: ciBaseTargetConfig.outputs, outputs: ciBaseTargetConfig.outputs,
dependsOn, dependsOn,
metadata: {
technologies: ['playwright'],
description: 'Runs Playwright Tests in CI',
},
}; };
ciTargetGroup.push(options.ciTargetName);
} }
return targets; return { targets, metadata };
} }
async function forEachTestFile( function forEachTestFile(
cb: (path: string) => void, cb: (path: string) => void,
opts: { opts: {
context: CreateNodesContext; context: CreateNodesContext;