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,
|
||||
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
|
||||
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).
|
||||
|
||||
### Request Interception
|
||||
|
||||
@@ -68,18 +68,21 @@
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
},
|
||||
"e2e-ci--src/*.e2e.ts": {
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["electron-backend"],
|
||||
"target": "build-e2e"
|
||||
},
|
||||
{
|
||||
"projects": ["stalker-mock-server", "xtream-mock-server"],
|
||||
"target": "serve"
|
||||
}
|
||||
]
|
||||
}
|
||||
"e2e-ci--src/*.e2e.ts": [
|
||||
{
|
||||
"filter": { "projects": ["electron-backend-e2e"] },
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["electron-backend"],
|
||||
"target": "build-e2e"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"filter": { "projects": ["web-e2e"] },
|
||||
"dependsOn": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user