Skip to content

Commit a63c2be

Browse files
committed
test: migrate i18n E2E tests to Puppeteer
Replaces the Protractor-based `ng e2e` execution with the new Puppeteer `executeBrowserTest` utility in the i18n E2E test suite. Refactors `setup.ts` to export a `browserCheck` helper function for verifying translated content, and removes the legacy Protractor spec file generation and configuration. Updates the following tests to use the new infrastructure: - ivy-localize-es2015-e2e - ivy-localize-basehref - ivy-localize-es2015 - ivy-localize-locale-data-augment - ivy-localize-sub-path
1 parent 95e35e5 commit a63c2be

File tree

6 files changed

+93
-86
lines changed

6 files changed

+93
-86
lines changed

tests/e2e/tests/i18n/ivy-localize-basehref.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
import { expectFileToMatch } from '../../utils/fs';
1010
import { ng } from '../../utils/process';
1111
import { updateJsonFile } from '../../utils/project';
12-
import { baseHrefs, externalServer, langTranslations, setupI18nConfig } from './setup';
12+
import { executeBrowserTest } from '../../utils/puppeteer';
13+
import { baseHrefs, browserCheck, externalServer, langTranslations, setupI18nConfig } from './setup';
1314

1415
export default async function () {
1516
// Setup i18n tests and config.
@@ -50,18 +51,15 @@ export default async function () {
5051
await expectFileToMatch(`${outputPath}/index.html`, `href="${baseHrefs[lang] || '/'}"`);
5152

5253
// Execute Application E2E tests for a production build without dev server
53-
const { server, port, url } = await externalServer(
54+
const { server, url } = await externalServer(
5455
outputPath,
5556
(baseHrefs[lang] as string) || '/',
5657
);
5758
try {
58-
await ng(
59-
'e2e',
60-
`--port=${port}`,
61-
`--configuration=${lang}`,
62-
'--dev-server-target=',
63-
`--base-url=${url}`,
64-
);
59+
await executeBrowserTest({
60+
baseUrl: url,
61+
checkFn: (page) => browserCheck(page, lang),
62+
});
6563
} finally {
6664
server.close();
6765
}
@@ -81,18 +79,15 @@ export default async function () {
8179
await expectFileToMatch(`${outputPath}/index.html`, `href="/test${baseHrefs[lang] || '/'}"`);
8280

8381
// Execute Application E2E tests for a production build without dev server
84-
const { server, port, url } = await externalServer(
82+
const { server, url } = await externalServer(
8583
outputPath,
8684
'/test' + (baseHrefs[lang] || '/'),
8785
);
8886
try {
89-
await ng(
90-
'e2e',
91-
`--port=${port}`,
92-
`--configuration=${lang}`,
93-
'--dev-server-target=',
94-
`--base-url=${url}`,
95-
);
87+
await executeBrowserTest({
88+
baseUrl: url,
89+
checkFn: (page) => browserCheck(page, lang),
90+
});
9691
} finally {
9792
server.close();
9893
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { getGlobalVariable } from '../../utils/env';
2-
import { ng } from '../../utils/process';
3-
import { langTranslations, setupI18nConfig } from './setup';
1+
import { executeBrowserTest } from '../../utils/puppeteer';
2+
import { browserCheck, langTranslations, setupI18nConfig } from './setup';
43

54
export default async function () {
65
// Setup i18n tests and config.
76
await setupI18nConfig();
87

98
for (const { lang } of langTranslations) {
10-
// Execute Application E2E tests with dev server
11-
await ng('e2e', `--configuration=${lang}`, '--port=0');
9+
await executeBrowserTest({
10+
configuration: lang,
11+
checkFn: (page) => browserCheck(page, lang),
12+
});
1213
}
13-
}
14+
}

tests/e2e/tests/i18n/ivy-localize-es2015.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { getGlobalVariable } from '../../utils/env';
22
import { expectFileToMatch } from '../../utils/fs';
33
import { ng } from '../../utils/process';
4+
import { executeBrowserTest } from '../../utils/puppeteer';
45
import { expectToFail } from '../../utils/utils';
5-
import { externalServer, langTranslations, setupI18nConfig } from './setup';
6+
import { browserCheck, externalServer, langTranslations, setupI18nConfig } from './setup';
67

78
export default async function () {
89
// Setup i18n tests and config.
@@ -32,15 +33,12 @@ export default async function () {
3233
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
3334

3435
// Execute Application E2E tests for a production build without dev server
35-
const { server, port, url } = await externalServer(outputPath, `/${lang}/`);
36+
const { server, url } = await externalServer(outputPath, `/${lang}/`);
3637
try {
37-
await ng(
38-
'e2e',
39-
`--port=${port}`,
40-
`--configuration=${lang}`,
41-
'--dev-server-target=',
42-
`--base-url=${url}`,
43-
);
38+
await executeBrowserTest({
39+
baseUrl: url,
40+
checkFn: (page) => browserCheck(page, lang),
41+
});
4442
} finally {
4543
server.close();
4644
}

tests/e2e/tests/i18n/ivy-localize-locale-data-augment.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import {
33
expectFileToMatch,
44
prependToFile,
55
readFile,
6-
replaceInFile,
76
writeFile,
87
} from '../../utils/fs';
98
import { ng } from '../../utils/process';
109
import { updateJsonFile } from '../../utils/project';
11-
import { langTranslations, setupI18nConfig } from './setup';
10+
import { executeBrowserTest } from '../../utils/puppeteer';
11+
import { browserCheck, langTranslations, setupI18nConfig } from './setup';
1212

1313
export default async function () {
1414
// Setup i18n tests and config.
@@ -20,9 +20,6 @@ export default async function () {
2020
appProject.architect['build'].options.localize = ['fr'];
2121
});
2222

23-
// Update E2E test to look for augmented locale data
24-
await replaceInFile('./e2e/src/app.fr.e2e-spec.ts', 'janvier', 'changed-janvier');
25-
2623
// Augment the locale data and import into the main application file
2724
const localeData = await readFile('node_modules/@angular/common/locales/global/fr.js');
2825
await writeFile('src/fr-changed.js', localeData.replace('janvier', 'changed-janvier'));
@@ -45,6 +42,27 @@ export default async function () {
4542
}
4643

4744
// Execute Application E2E tests with dev server
48-
await ng('e2e', `--configuration=${lang}`, '--port=0');
45+
await executeBrowserTest({
46+
configuration: lang,
47+
checkFn: async (page) => {
48+
// Run standard checks but expect failure on date
49+
try {
50+
await browserCheck(page, lang);
51+
throw new Error('Expected browserCheck to fail due to modified locale data');
52+
} catch (e) {
53+
if (!(e instanceof Error) || !e.message.includes("Expected 'date' to be")) {
54+
throw e;
55+
}
56+
}
57+
58+
// Verify the modified date
59+
const getParagraph = async (id: string) =>
60+
page.$eval(`p#${id}`, (el) => el.textContent?.trim());
61+
const date = await getParagraph('date');
62+
if (date !== 'changed-janvier') {
63+
throw new Error(`Expected 'date' to be 'changed-janvier', but got '${date}'.`);
64+
}
65+
},
66+
});
4967
}
5068
}

tests/e2e/tests/i18n/ivy-localize-sub-path.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import { join } from 'node:path';
1010
import { expectFileToMatch } from '../../utils/fs';
1111
import { ng } from '../../utils/process';
1212
import { updateJsonFile } from '../../utils/project';
13-
import { baseDir, baseHrefs, externalServer, langTranslations, setupI18nConfig } from './setup';
13+
import { executeBrowserTest } from '../../utils/puppeteer';
14+
import {
15+
baseDir,
16+
browserCheck,
17+
externalServer,
18+
langTranslations,
19+
setupI18nConfig,
20+
} from './setup';
1421

1522
export default async function () {
1623
// Setup i18n tests and config.
@@ -56,16 +63,13 @@ export default async function () {
5663
await expectFileToMatch(`${outputPath}/index.html`, `href="${baseHref}"`);
5764

5865
// Execute Application E2E tests for a production build without dev server
59-
const { server, port, url } = await externalServer(outputPath, baseHref);
66+
const { server, url } = await externalServer(outputPath, baseHref);
6067

6168
try {
62-
await ng(
63-
'e2e',
64-
`--port=${port}`,
65-
`--configuration=${lang}`,
66-
'--dev-server-target=',
67-
`--base-url=${url}`,
68-
);
69+
await executeBrowserTest({
70+
baseUrl: url,
71+
checkFn: (page) => browserCheck(page, lang),
72+
});
6973
} finally {
7074
server.close();
7175
}

tests/e2e/tests/i18n/setup.ts

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { updateJsonFile } from '../../utils/project';
77
import { readNgVersion } from '../../utils/version';
88
import { Server } from 'node:http';
99
import { AddressInfo } from 'node:net';
10+
import type { Page } from 'puppeteer';
1011

1112
// Configurations for each locale.
1213
const translationFile = 'src/locale/messages.xlf';
@@ -61,6 +62,35 @@ export const langTranslations = [
6162
];
6263
export const sourceLocale = langTranslations[0].lang;
6364

65+
export async function browserCheck(page: Page, lang: string) {
66+
const translation = langTranslations.find((t) => t.lang === lang)?.translation;
67+
if (!translation) {
68+
throw new Error(`Could not find translation for language '${lang}'`);
69+
}
70+
71+
const getParagraph = async (id: string) => page.$eval(`p#${id}`, (el) => el.textContent?.trim());
72+
73+
const hello = await getParagraph('hello');
74+
if (hello !== translation.hello) {
75+
throw new Error(`Expected 'hello' to be '${translation.hello}', but got '${hello}'.`);
76+
}
77+
78+
const locale = await getParagraph('locale');
79+
if (locale !== lang) {
80+
throw new Error(`Expected 'locale' to be '${lang}', but got '${locale}'.`);
81+
}
82+
83+
const date = await getParagraph('date');
84+
if (date !== translation.date) {
85+
throw new Error(`Expected 'date' to be '${translation.date}', but got '${date}'.`);
86+
}
87+
88+
const plural = await getParagraph('plural');
89+
if (plural !== translation.plural) {
90+
throw new Error(`Expected 'plural' to be '${translation.plural}', but got '${plural}'.`);
91+
}
92+
}
93+
6494
export interface ExternalServer {
6595
readonly server: Server;
6696
readonly port: number;
@@ -173,47 +203,12 @@ export async function setupI18nConfig() {
173203
`,
174204
);
175205

176-
// Add e2e specs for each lang.
177-
for (const { lang, translation } of langTranslations) {
178-
await writeFile(
179-
`./e2e/src/app.${lang}.e2e-spec.ts`,
180-
`
181-
import { browser, logging, element, by } from 'protractor';
182-
183-
describe('workspace-project App', () => {
184-
const getParagraph = async (name: string) => element(by.css('app-root p#' + name)).getText();
185-
beforeEach(() => browser.get(browser.baseUrl));
186-
afterEach(async () => {
187-
// Assert that there are no errors emitted from the browser
188-
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
189-
expect(logs).not.toContain(jasmine.objectContaining({
190-
level: logging.Level.SEVERE,
191-
} as logging.Entry));
192-
});
193-
194-
it('should display welcome message', async () =>
195-
expect(await getParagraph('hello')).toEqual('${translation.hello}'));
196-
197-
it('should display locale', async () =>
198-
expect(await getParagraph('locale')).toEqual('${lang}'));
199-
200-
it('should display localized date', async () =>
201-
expect(await getParagraph('date')).toEqual('${translation.date}'));
202-
203-
it('should display pluralized message', async () =>
204-
expect(await getParagraph('plural')).toEqual('${translation.plural}'));
205-
});
206-
`,
207-
);
208-
}
209-
210206
// Update angular.json to build, serve, and test each locale.
211207
await updateJsonFile('angular.json', (workspaceJson) => {
212208
const appProject = workspaceJson.projects['test-project'];
213209
const appArchitect = workspaceJson.projects['test-project'].architect;
214210
const buildConfigs = appArchitect['build'].configurations;
215211
const serveConfigs = appArchitect['serve'].configurations;
216-
const e2eConfigs = appArchitect['e2e'].configurations;
217212

218213
appArchitect['build'].defaultConfiguration = undefined;
219214

@@ -245,10 +240,6 @@ export async function setupI18nConfig() {
245240

246241
buildConfigs[lang] = { localize: [lang] };
247242
serveConfigs[lang] = { buildTarget: `test-project:build:${lang}` };
248-
e2eConfigs[lang] = {
249-
specs: [`./src/app.${lang}.e2e-spec.ts`],
250-
devServerTarget: `test-project:serve:${lang}`,
251-
};
252243
}
253244
});
254245

0 commit comments

Comments
 (0)