Skip to content

Commit 24d0f7a

Browse files
alan-agius4vikerman
authored andcommitted
test: clean up ivy-localize tests and add i18n server test
1 parent 0686cef commit 24d0f7a

File tree

5 files changed

+201
-14
lines changed

5 files changed

+201
-14
lines changed

tests/legacy-cli/e2e/tests/build/platform-server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default async function () {
99
const argv = getGlobalVariable('argv');
1010
const veEnabled = argv['ve'];
1111

12-
await ng('add', '@nguniversal/express-engine@9.0.0-next.5');
12+
await ng('add', '@nguniversal/express-engine@9.0.0-next.6');
1313

1414
await updateJsonFile('package.json', packageJson => {
1515
const dependencies = packageJson['dependencies'];

tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import { expectToFail } from '../../utils/utils';
1515
import { readNgVersion } from '../../utils/version';
1616

1717
export default async function() {
18-
if (getGlobalVariable('argv').ve) {
19-
return;
20-
}
21-
2218
let localizeVersion = '@angular/localize@' + readNgVersion();
2319
if (getGlobalVariable('argv')['ng-snapshots']) {
2420
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
@@ -36,7 +32,6 @@ export default async function() {
3632
const langTranslations = [
3733
{ lang: 'en-US', translation: 'Hello i18n!' },
3834
{ lang: 'fr', translation: 'Bonjour i18n!' },
39-
{ lang: 'de', translation: 'Hallo i18n!' },
4035
];
4136

4237
await updateJsonFile('angular.json', workspaceJson => {

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ import { expectToFail } from '../../utils/utils';
1616
import { readNgVersion } from '../../utils/version';
1717

1818
export default async function() {
19-
if (getGlobalVariable('argv').ve) {
20-
return;
21-
}
22-
2319
let localizeVersion = '@angular/localize@' + readNgVersion();
2420
if (getGlobalVariable('argv')['ng-snapshots']) {
2521
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];

tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ import { expectToFail } from '../../utils/utils';
1616
import { readNgVersion } from '../../utils/version';
1717

1818
export default async function() {
19-
if (getGlobalVariable('argv').ve) {
20-
return;
21-
}
22-
2319
let localizeVersion = '@angular/localize@' + readNgVersion();
2420
if (getGlobalVariable('argv')['ng-snapshots']) {
2521
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import * as express from 'express';
2+
import * as http from "http";
3+
import { join } from 'path';
4+
import { getGlobalVariable } from '../../utils/env';
5+
import {
6+
appendToFile,
7+
copyFile,
8+
expectFileToMatch,
9+
replaceInFile,
10+
writeFile,
11+
} from '../../utils/fs';
12+
import { ng, npm } from '../../utils/process';
13+
import { updateJsonFile } from '../../utils/project';
14+
import { expectToFail } from '../../utils/utils';
15+
import { readNgVersion } from '../../utils/version';
16+
17+
export default async function () {
18+
let localizeVersion = '@angular/localize@' + readNgVersion();
19+
if (getGlobalVariable('argv')['ng-snapshots']) {
20+
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
21+
}
22+
23+
await npm('install', `${localizeVersion}`);
24+
25+
// Add universal to the project
26+
await ng('add', '@nguniversal/express-engine@9.0.0-next.6');
27+
28+
await npm('run', 'webdriver-update');
29+
30+
const serverbaseDir = 'dist/test-project/server';
31+
const serverBuildArgs = ['run', 'test-project:server'];
32+
33+
// Set configurations for each locale.
34+
const langTranslations = [
35+
{ lang: 'en-US', translation: 'Hello i18n!' },
36+
{ lang: 'fr', translation: 'Bonjour i18n!' },
37+
{ lang: 'de', translation: 'Hallo i18n!' },
38+
];
39+
40+
await updateJsonFile('angular.json', workspaceJson => {
41+
const appProject = workspaceJson.projects['test-project'];
42+
const appArchitect = appProject.architect || appProject.targets;
43+
const buildOptions = appArchitect['build'].options;
44+
const serverOptions = appArchitect['server'].options;
45+
46+
// Make default builds prod.
47+
buildOptions.optimization = true;
48+
buildOptions.buildOptimizer = true;
49+
buildOptions.aot = true;
50+
buildOptions.fileReplacements = [
51+
{
52+
replace: 'src/environments/environment.ts',
53+
with: 'src/environments/environment.prod.ts',
54+
},
55+
];
56+
57+
serverOptions.optimization = true;
58+
serverOptions.fileReplacements = [
59+
{
60+
replace: 'src/environments/environment.ts',
61+
with: 'src/environments/environment.prod.ts',
62+
},
63+
];
64+
65+
// Enable localization for all locales
66+
buildOptions.localize = true;
67+
serverOptions.localize = true;
68+
69+
// Add locale definitions to the project
70+
// tslint:disable-next-line: no-any
71+
const i18n: Record<string, any> = (appProject.i18n = { locales: {} });
72+
for (const { lang } of langTranslations) {
73+
if (lang == 'en-US') {
74+
i18n.sourceLocale = lang;
75+
} else {
76+
i18n.locales[lang] = `src/locale/messages.${lang}.xlf`;
77+
}
78+
}
79+
});
80+
81+
// Add a translatable element.
82+
await writeFile(
83+
'src/app/app.component.html',
84+
'<h1 i18n="An introduction header for this sample">Hello i18n!</h1>',
85+
);
86+
87+
// Override 'main.ts' so that we never bootstrap the client side
88+
// This is needed so that we can we can run E2E test against the server view
89+
await writeFile(
90+
'src/main.ts',
91+
`
92+
import { enableProdMode } from '@angular/core';
93+
94+
import { AppModule } from './app/app.module';
95+
import { environment } from './environments/environment';
96+
97+
if (environment.production) {
98+
enableProdMode();
99+
}
100+
`,
101+
);
102+
103+
// By default the 'server.ts' doesn't support localized dist folders,
104+
// so we create a copy of 'app' function with a locale parameter.
105+
await appendToFile(
106+
'server.ts',
107+
`
108+
export function i18nApp(locale: string) {
109+
const server = express();
110+
const distFolder = join(process.cwd(), \`dist/test-project/browser/\${locale}\`);
111+
112+
server.engine('html', ngExpressEngine({
113+
bootstrap: AppServerModule,
114+
}));
115+
116+
server.set('view engine', 'html');
117+
server.set('views', distFolder);
118+
119+
server.get('*.*', express.static(distFolder, {
120+
maxAge: '1y'
121+
}));
122+
123+
server.get('*', (req, res) => {
124+
res.render('index', { req });
125+
});
126+
127+
return server;
128+
}
129+
`,
130+
);
131+
132+
// Extract the translation messages and copy them for each language.
133+
await ng('xi18n', '--output-path=src/locale');
134+
135+
for (const { lang, translation } of langTranslations) {
136+
if (lang !== 'en-US') {
137+
await copyFile('src/locale/messages.xlf', `src/locale/messages.${lang}.xlf`);
138+
await replaceInFile(
139+
`src/locale/messages.${lang}.xlf`,
140+
'source-language="en-US"',
141+
`source-language="en-US" target-language="${lang}"`,
142+
);
143+
await replaceInFile(
144+
`src/locale/messages.${lang}.xlf`,
145+
'<source>Hello i18n!</source>',
146+
`<source>Hello i18n!</source>\n<target>${translation}</target>`,
147+
);
148+
}
149+
}
150+
151+
// Build each locale and verify the output.
152+
await ng('build', '--i18n-missing-translation', 'error');
153+
await ng(...serverBuildArgs, '--i18n-missing-translation', 'error');
154+
155+
for (const { lang, translation } of langTranslations) {
156+
await expectFileToMatch(`${serverbaseDir}/${lang}/main.js`, translation);
157+
await expectToFail(() => expectFileToMatch(`${serverbaseDir}/${lang}/main.js`, '$localize`'));
158+
159+
// Add E2E test for locale
160+
await writeFile(
161+
'e2e/src/app.e2e-spec.ts',
162+
`
163+
import { browser, logging, by } from 'protractor';
164+
describe('workspace-project App', () => {
165+
it('should display welcome message', () => {
166+
// Load the page without waiting for Angular since it is not bootstrapped automatically.
167+
browser.driver.get(browser.baseUrl);
168+
169+
const header = browser.driver.findElement(by.css('h1'));
170+
expect(header.getText()).toEqual('${translation}');
171+
});
172+
afterEach(async () => {
173+
// Assert that there are no errors emitted from the browser
174+
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
175+
expect(logs).not.toContain(jasmine.objectContaining({
176+
level: logging.Level.SEVERE,
177+
} as logging.Entry));
178+
});
179+
});
180+
`,
181+
);
182+
183+
// Run the server
184+
const serverBundle = join(process.cwd(), `${serverbaseDir}/${lang}/main.js`);
185+
const { i18nApp } = await import(serverBundle) as { i18nApp(locale: string): express.Express };
186+
const server = i18nApp(lang).listen(4200, 'localhost');
187+
try {
188+
// Execute without a devserver.
189+
await ng('e2e', '--devServerTarget=');
190+
} finally {
191+
server.close();
192+
}
193+
}
194+
195+
// Verify missing translation behaviour.
196+
await appendToFile('src/app/app.component.html', '<p i18n>Other content</p>');
197+
await ng(...serverBuildArgs, '--i18n-missing-translation', 'ignore');
198+
await expectFileToMatch(`${serverbaseDir}/fr/main.js`, /Other content/);
199+
await expectToFail(() => ng(...serverBuildArgs, '--i18n-missing-translation', 'error'));
200+
}

0 commit comments

Comments
 (0)