mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
fix(e2e): let per-file E2E targets run without mock serve dependencies (#1772)
* fix(e2e): let per-file E2E targets run without mock serve dependencies Since #1710 the Playwright configs start the Stalker and Xtream mocks themselves (`node --import tsx …`), so @nx/playwright can no longer map those webServers to Nx tasks and infers the atomized `e2e-ci--*` targets as non-parallel. The `e2e-ci--src/*.e2e.ts` target default still made them depend on the continuous `stalker-mock-server:serve` and `xtream-mock-server:serve` targets, and Nx refuses to run a non-parallel task with continuous dependencies, so every per-file target failed before running anything. Drop the redundant mock dependencies and keep the Electron build. The mock-launch guard spec now also rejects any nx.json target default that depends on a mock-server task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(e2e): scope the mock dependency guard to E2E targets Check only the `e2e*` target defaults in nx.json, so an unrelated default may still depend on a mock, and also check every target in the `apps/*-e2e` project.json files, where a mock `serve` dependency would break the same targets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(e2e): build Electron only before Electron per-file E2E targets The `e2e-ci--src/*.e2e.ts` target default also matched web-e2e, so every browser-only per-file target built electron-backend first. Split it into project-filtered entries: Electron targets keep `build-e2e`, web targets get an empty dependency list (which also keeps the inferred `web:serve` dependency, rejected by Nx on a non-parallel target, out of them). The mock dependency guard now also catches `^serve`-style dependencies, which schedule the mocks through the E2E projects' implicit dependencies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: 4gray <fourgray@proton.me> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
3 files changed
+116
-13
No files matched your search
@@ -87,3 +87,99 @@ describe('Playwright mock-server launch', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Nx E2E task dependencies', () => {
|
||||||
|
type Dependency =
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
projects?: string | string[];
|
||||||
|
dependencies?: boolean;
|
||||||
|
target?: string;
|
||||||
|
};
|
||||||
|
type TargetConfig = {
|
||||||
|
dependsOn?: Dependency[];
|
||||||
|
continuous?: boolean;
|
||||||
|
filter?: { projects?: string[] };
|
||||||
|
};
|
||||||
|
type ProjectJson = { targets: Record<string, TargetConfig> };
|
||||||
|
const readJson = <T>(path: string) =>
|
||||||
|
JSON.parse(readFileSync(join(process.cwd(), path), 'utf8')) as T;
|
||||||
|
const nxJson = readJson<{
|
||||||
|
targetDefaults: Record<string, TargetConfig | TargetConfig[]>;
|
||||||
|
}>('nx.json');
|
||||||
|
const appNames = readdirSync(join(process.cwd(), 'apps'));
|
||||||
|
const e2eProjectFiles = appNames
|
||||||
|
.filter((name) => name.endsWith('-e2e'))
|
||||||
|
.map((name) => `apps/${name}/project.json`);
|
||||||
|
// The E2E projects list the mocks as implicit dependencies, so a `^serve`
|
||||||
|
// dependency schedules the mock serve tasks as well.
|
||||||
|
const mockContinuousTargets = new Set(
|
||||||
|
appNames
|
||||||
|
.filter((name) => name.endsWith('-mock-server'))
|
||||||
|
.flatMap((name) =>
|
||||||
|
Object.entries(
|
||||||
|
readJson<ProjectJson>(`apps/${name}/project.json`).targets
|
||||||
|
)
|
||||||
|
.filter(([, target]) => target.continuous)
|
||||||
|
.map(([targetName]) => targetName)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const dependsOnMock = (dependency: Dependency) =>
|
||||||
|
typeof dependency === 'string'
|
||||||
|
? dependency.includes('-mock-server:') ||
|
||||||
|
(dependency.startsWith('^') &&
|
||||||
|
mockContinuousTargets.has(dependency.slice(1)))
|
||||||
|
: [dependency.projects ?? []]
|
||||||
|
.flat()
|
||||||
|
.some((project) => project.includes('-mock-server')) ||
|
||||||
|
(dependency.dependencies === true &&
|
||||||
|
mockContinuousTargets.has(dependency.target ?? ''));
|
||||||
|
const perFileDefaultFor = (project: string) =>
|
||||||
|
[nxJson.targetDefaults['e2e-ci--src/*.e2e.ts'] ?? []]
|
||||||
|
.flat()
|
||||||
|
.find((entry) => entry.filter?.projects?.includes(project));
|
||||||
|
|
||||||
|
// The Playwright configs start the mocks themselves, so @nx/playwright
|
||||||
|
// infers their E2E targets as non-parallel, and Nx refuses to run a
|
||||||
|
// non-parallel task that depends on a continuous `serve` task.
|
||||||
|
it('never makes an E2E target depend on a mock-server task', () => {
|
||||||
|
const e2eDefaults = Object.entries(nxJson.targetDefaults)
|
||||||
|
.filter(([targetName]) => targetName.startsWith('e2e'))
|
||||||
|
.flatMap(([targetName, config]) =>
|
||||||
|
[config].flat().map((entry) => ({
|
||||||
|
source: `nx.json ${targetName}`,
|
||||||
|
config: entry,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
const e2eProjectTargets = e2eProjectFiles.flatMap((path) =>
|
||||||
|
Object.entries(readJson<ProjectJson>(path).targets).map(
|
||||||
|
([targetName, config]) => ({
|
||||||
|
source: `${path} ${targetName}`,
|
||||||
|
config,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const mockDependencies = [...e2eDefaults, ...e2eProjectTargets]
|
||||||
|
.map(({ source, config }) => ({
|
||||||
|
source,
|
||||||
|
dependencies: (config.dependsOn ?? []).filter(dependsOnMock),
|
||||||
|
}))
|
||||||
|
.filter(({ dependencies }) => dependencies.length > 0);
|
||||||
|
|
||||||
|
expect(e2eProjectFiles).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
'apps/electron-backend-e2e/project.json',
|
||||||
|
'apps/web-e2e/project.json',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
expect([...mockContinuousTargets]).toContain('serve');
|
||||||
|
expect(mockDependencies).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('builds the Electron app only before Electron per-file E2E targets', () => {
|
||||||
|
expect(perFileDefaultFor('electron-backend-e2e')?.dependsOn).toEqual([
|
||||||
|
{ projects: ['electron-backend'], target: 'build-e2e' },
|
||||||
|
]);
|
||||||
|
expect(perFileDefaultFor('web-e2e')?.dependsOn).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -579,7 +579,11 @@ for the serve target's `--tsconfig` flag and is required for the `@iptvnator/*`
|
|||||||
path aliases. `project-config.spec.ts` pins which configs start which mock,
|
path aliases. `project-config.spec.ts` pins which configs start which mock,
|
||||||
and fails if any of them launches a mock through Nx or a new config starts one
|
and fails if any of them launches a mock through Nx or a new config starts one
|
||||||
without being listed there. The `serve` targets remain the entry point
|
without being listed there. The `serve` targets remain the entry point
|
||||||
for starting a mock by hand. The web-e2e `web-backend` entry uses the same
|
for starting a mock by hand, and no E2E target may depend on them: with no
|
||||||
|
Nx-launched server, `@nx/playwright` infers the atomized `e2e-ci--*` targets
|
||||||
|
as non-parallel, and Nx refuses to run a non-parallel task that depends on a
|
||||||
|
continuous `serve` task. The same spec guards the `e2e*` entries of `nx.json`
|
||||||
|
`targetDefaults` and every target in the `apps/*-e2e` `project.json` files. The web-e2e `web-backend` entry uses the same
|
||||||
launch form; see [PWA web backend](pwa-self-hosted.md#web-backend).
|
launch form; see [PWA web backend](pwa-self-hosted.md#web-backend).
|
||||||
|
|
||||||
### Request Interception
|
### Request Interception
|
||||||
|
|||||||
@@ -68,18 +68,21 @@
|
|||||||
"dependsOn": ["^build"],
|
"dependsOn": ["^build"],
|
||||||
"inputs": ["production", "^production"]
|
"inputs": ["production", "^production"]
|
||||||
},
|
},
|
||||||
"e2e-ci--src/*.e2e.ts": {
|
"e2e-ci--src/*.e2e.ts": [
|
||||||
"dependsOn": [
|
{
|
||||||
{
|
"filter": { "projects": ["electron-backend-e2e"] },
|
||||||
"projects": ["electron-backend"],
|
"dependsOn": [
|
||||||
"target": "build-e2e"
|
{
|
||||||
},
|
"projects": ["electron-backend"],
|
||||||
{
|
"target": "build-e2e"
|
||||||
"projects": ["stalker-mock-server", "xtream-mock-server"],
|
}
|
||||||
"target": "serve"
|
]
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
}
|
"filter": { "projects": ["web-e2e"] },
|
||||||
|
"dependsOn": []
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user