mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
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>
This commit is contained in:
1 parent
abb7e5fa41
commit
311f73ce7a
2 files changed
+65
-28
No files matched your search
@@ -89,22 +89,55 @@ describe('Playwright mock-server launch', () => {
|
||||
});
|
||||
|
||||
describe('Nx E2E task dependencies', () => {
|
||||
type Dependency = string | { projects?: string | string[] };
|
||||
type TargetConfig = { dependsOn?: Dependency[] };
|
||||
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 e2eProjectFiles = readdirSync(join(process.cwd(), 'apps'))
|
||||
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.includes('-mock-server:') ||
|
||||
(dependency.startsWith('^') &&
|
||||
mockContinuousTargets.has(dependency.slice(1)))
|
||||
: [dependency.projects ?? []]
|
||||
.flat()
|
||||
.some((project) => project.includes('-mock-server'));
|
||||
.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
|
||||
@@ -119,13 +152,12 @@ describe('Nx E2E task dependencies', () => {
|
||||
}))
|
||||
);
|
||||
const e2eProjectTargets = e2eProjectFiles.flatMap((path) =>
|
||||
Object.entries(
|
||||
readJson<{ targets: Record<string, TargetConfig> }>(path)
|
||||
.targets
|
||||
).map(([targetName, config]) => ({
|
||||
source: `${path} ${targetName}`,
|
||||
config,
|
||||
}))
|
||||
Object.entries(readJson<ProjectJson>(path).targets).map(
|
||||
([targetName, config]) => ({
|
||||
source: `${path} ${targetName}`,
|
||||
config,
|
||||
})
|
||||
)
|
||||
);
|
||||
const mockDependencies = [...e2eDefaults, ...e2eProjectTargets]
|
||||
.map(({ source, config }) => ({
|
||||
@@ -140,16 +172,14 @@ describe('Nx E2E task dependencies', () => {
|
||||
'apps/web-e2e/project.json',
|
||||
])
|
||||
);
|
||||
expect([...mockContinuousTargets]).toContain('serve');
|
||||
expect(mockDependencies).toEqual([]);
|
||||
});
|
||||
|
||||
it('still builds the Electron app before each per-file E2E target', () => {
|
||||
expect(
|
||||
(nxJson.targetDefaults['e2e-ci--src/*.e2e.ts'] as TargetConfig)
|
||||
.dependsOn
|
||||
).toContainEqual({
|
||||
projects: ['electron-backend'],
|
||||
target: 'build-e2e',
|
||||
});
|
||||
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([]);
|
||||
});
|
||||
});
|
||||
@@ -68,14 +68,21 @@
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
},
|
||||
"e2e-ci--src/*.e2e.ts": {
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["electron-backend"],
|
||||
"target": "build-e2e"
|
||||
}
|
||||
]
|
||||
}
|
||||
"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