Skip to content

Commit 5b8b628

Browse files
filipesilvavikerman
authored andcommitted
test: additional i18n e2e tests
1 parent c1051b5 commit 5b8b628

File tree

1 file changed

+107
-59
lines changed

1 file changed

+107
-59
lines changed

tests/legacy-cli/e2e/tests/build/aot/aot-i18n.ts

Lines changed: 107 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,122 @@
1-
import { appendToFile, createDir, expectFileToMatch, writeFile } from '../../../utils/fs';
1+
import * as express from 'express';
2+
import { resolve } from 'path';
3+
import { getGlobalVariable } from '../../../utils/env';
4+
import { appendToFile, copyFile, expectFileToExist, expectFileToMatch, replaceInFile, writeFile } from '../../../utils/fs';
25
import { ng } from '../../../utils/process';
36
import { updateJsonFile } from '../../../utils/project';
47
import { expectToFail } from '../../../utils/utils';
58

69
export default async function () {
7-
const enDir = 'dist/test-project';
8-
const frDist = `${enDir}-fr`;
9-
const deDir = `${enDir}-de`;
10+
const baseDir = 'dist/test-project';
11+
const enDir = `${baseDir}/en`;
12+
const frDist = `${baseDir}/fr`;
13+
const deDir = `${baseDir}/de`;
14+
15+
// Set configurations for each locale.
16+
const langTranslations = [
17+
{ lang: 'en', translation: 'Hello i18n!', outputPath: enDir },
18+
{ lang: 'fr', translation: 'Bonjour i18n!', outputPath: frDist },
19+
{ lang: 'de', translation: 'Hallo i18n!', outputPath: deDir },
20+
];
1021

1122
await updateJsonFile('angular.json', workspaceJson => {
1223
const appArchitect = workspaceJson.projects['test-project'].architect;
1324
const browserConfigs = appArchitect['build'].configurations;
14-
browserConfigs['fr'] = {
15-
outputPath: frDist,
16-
aot: true,
17-
i18nFile: 'src/locale/messages.fr.xlf',
18-
i18nFormat: 'xlf',
19-
i18nLocale: 'fr',
20-
};
21-
browserConfigs['de'] = {
22-
outputPath: deDir,
23-
aot: true,
24-
i18nFile: 'src/locale/messages.de.xlf',
25-
i18nFormat: 'xlf',
26-
i18nLocale: 'de',
27-
};
25+
const serveConfigs = appArchitect['serve'].configurations;
26+
const e2eConfigs = appArchitect['e2e'].configurations;
27+
28+
// Make default builds prod.
29+
appArchitect['build'].options.optimization = true;
30+
appArchitect['build'].options.buildOptimizer = true;
31+
appArchitect['build'].options.aot = true;
32+
appArchitect['build'].options.fileReplacements = [{
33+
replace: 'src/environments/environment.ts',
34+
with: 'src/environments/environment.prod.ts',
35+
}];
36+
37+
for (const { lang, outputPath } of langTranslations) {
38+
if (lang == 'en') {
39+
browserConfigs[lang] = { outputPath };
40+
} else {
41+
browserConfigs[lang] = {
42+
outputPath,
43+
i18nFile: `src/locale/messages.${lang}.xlf`,
44+
i18nFormat: `xlf`,
45+
i18nLocale: lang,
46+
};
47+
}
48+
serveConfigs[lang] = { browserTarget: `test-project:build:${lang}` };
49+
e2eConfigs[lang] = {
50+
specs: [`./src/app.${lang}.e2e-spec.ts`],
51+
devServerTarget: `test-project:serve:${lang}`,
52+
};
53+
}
2854
});
2955

30-
await createDir('src/locale');
31-
await writeFile('src/locale/messages.fr.xlf', `
32-
<?xml version="1.0" encoding="UTF-8" ?>
33-
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
34-
<file source-language="en" datatype="plaintext" original="ng2.template">
35-
<body>
36-
<trans-unit id="8def8481e91291a52f9baa31cbdb313e6a6ca02b" datatype="html">
37-
<source>Hello i18n!</source>
38-
<target>Bonjour i18n!</target>
39-
<note priority="1" from="description">An introduction header for this sample</note>
40-
</trans-unit>
41-
</body>
42-
</file>
43-
</xliff>`);
44-
await writeFile('src/locale/messages.de.xlf', `
45-
<?xml version="1.0" encoding="UTF-8" ?>
46-
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
47-
<file source-language="en" datatype="plaintext" original="ng2.template">
48-
<body>
49-
<trans-unit id="8def8481e91291a52f9baa31cbdb313e6a6ca02b" datatype="html">
50-
<source>Hello i18n!</source>
51-
<target>Hallo i18n!</target>
52-
<note priority="1" from="description">An introduction header for this sample</note>
53-
</trans-unit>
54-
</body>
55-
</file>
56-
</xliff>`);
57-
await appendToFile('src/app/app.component.html',
56+
// Add e2e specs for each lang.
57+
for (const { lang, translation } of langTranslations) {
58+
await writeFile(`./src/app.${lang}.e2e-spec.ts`, `
59+
import { browser, logging, element, by } from 'protractor';
60+
61+
describe('workspace-project App', () => {
62+
it('should display welcome message', () => {
63+
browser.get(browser.baseUrl);
64+
expect(element(by.css('h1')).getText()).toEqual('${translation}');
65+
});
66+
67+
afterEach(async () => {
68+
// Assert that there are no errors emitted from the browser
69+
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
70+
expect(logs).not.toContain(jasmine.objectContaining({
71+
level: logging.Level.SEVERE,
72+
} as logging.Entry));
73+
});
74+
});
75+
`);
76+
}
77+
78+
// Add a translatable element.
79+
await writeFile('src/app/app.component.html',
5880
'<h1 i18n="An introduction header for this sample">Hello i18n!</h1>');
59-
await ng('build', '--configuration=fr');
60-
await expectFileToMatch(`${frDist}/main-es5.js`, /Bonjour i18n!/);
61-
await expectFileToMatch(`${frDist}/main-es2015.js`, /Bonjour i18n!/);
62-
await ng('build', '--configuration=de');
63-
await expectFileToMatch(`${deDir}/main-es5.js`, /Hallo i18n!/);
64-
await expectFileToMatch(`${deDir}/main-es2015.js`, /Hallo i18n!/);
65-
await ng('build', '--aot');
66-
await expectToFail(() => expectFileToMatch(`${enDir}/main-es5.js`, /Bonjour i18n!/));
67-
await expectToFail(() => expectFileToMatch(`${enDir}/main-es2015.js`, /Bonjour i18n!/));
68-
await expectToFail(() => expectFileToMatch(`${enDir}/main-es5.js`, /Hallo i18n!/));
69-
await expectToFail(() => expectFileToMatch(`${enDir}/main-es2015.js`, /Hallo i18n!/));
70-
await expectFileToMatch(`${enDir}/main-es2015.js`, /Hello i18n!/);
71-
await expectFileToMatch(`${enDir}/main-es5.js`, /Hello i18n!/);
81+
82+
// Extract the translation messages and copy them for each language.
83+
await ng('xi18n', '--output-path=src/locale');
84+
await expectFileToExist('src/locale/messages.xlf');
85+
await expectFileToMatch('src/locale/messages.xlf', `source-language="en"`);
86+
await expectFileToMatch('src/locale/messages.xlf', `An introduction header for this sample`);
87+
88+
for (const { lang, translation } of langTranslations) {
89+
if (lang != 'en') {
90+
await copyFile('src/locale/messages.xlf', `src/locale/messages.${lang}.xlf`);
91+
await replaceInFile(`src/locale/messages.${lang}.xlf`, '<source>Hello i18n!</source>',
92+
`<source>Hello i18n!</source>\n<target>${translation}</target>`);
93+
}
94+
}
95+
96+
for (const { lang, translation, outputPath } of langTranslations) {
97+
// Build each locale and verify the output.
98+
await ng('build', `--configuration=${lang}`);
99+
await expectFileToMatch(`${outputPath}/main-es5.js`, translation);
100+
await expectFileToMatch(`${outputPath}/main-es2015.js`, translation);
101+
102+
// E2E to verify the output runs and is correct.
103+
if (getGlobalVariable('argv')['ve']) {
104+
await ng('e2e', `--configuration=${lang}`);
105+
} else {
106+
// Ivy i18n doesn't yet work with `ng serve` so we must use a separate server.
107+
const app = express();
108+
app.use(express.static(resolve(outputPath)));
109+
const server = app.listen(4200, 'localhost');
110+
try {
111+
// Execute without a devserver.
112+
await ng('e2e', '--devServerTarget=');
113+
} finally {
114+
server.close();
115+
}
116+
}
117+
}
118+
119+
// Verify missing translation behaviour.
72120
await appendToFile('src/app/app.component.html', '<p i18n>Other content</p>');
73121
await ng('build', '--configuration=fr', '--i18n-missing-translation', 'ignore');
74122
await expectFileToMatch(`${frDist}/main-es5.js`, /Other content/);

0 commit comments

Comments
 (0)