Skip to content

Commit

Permalink
test(e2e): Add local npm registry for testing (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-bompart authored Apr 8, 2021
1 parent 44cae70 commit 37d119b
Show file tree
Hide file tree
Showing 25 changed files with 473 additions and 323 deletions.
21 changes: 2 additions & 19 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ jobs:
env:
PLATFORM_USER_NAME: ${{ secrets.PLATFORM_USER_NAME }}
PLATFORM_USER_PASSWORD: ${{ secrets.PLATFORM_USER_PASSWORD }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
Expand All @@ -24,27 +23,11 @@ jobs:
- name: Build CLI
working-directory: ./packages/cli
run: tsc -b
- name: Set the template version
run: |
node scripts/store-next-test-version.js --variable=UI_TEMPLATE_VERSION --output=$GITHUB_ENV
- name: Bump template versions
run: |
echo "E2E tests should target template version ${{ env.UI_TEMPLATE_VERSION }}"
echo "//registry.npmjs.org/:_authToken=${{ env.NPM_TOKEN }}" > ~/.npmrc
npm run npm:bump:template -- -- ${{ env.UI_TEMPLATE_VERSION }}
npm run npm:publish:template
node scripts/wait-for-published-packages.js -v ${{ env.UI_TEMPLATE_VERSION }}
- uses: actions/upload-artifact@v2
if: failure()
with:
name: npm-logs
path: /home/runner/.npm/_logs/*debug.log
- name: End-to-end Tests
working-directory: ./packages/cli-e2e
run: |
echo "Running E2E tests with version ${{ env.UI_TEMPLATE_VERSION }}"
npm run test-e2e
run: npm run test-e2e
- uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: test-screenshots
path: ./packages/cli-e2e/screenshots
2 changes: 1 addition & 1 deletion packages/angular/src/search-token-server/rules/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function startProxyServerFromRootApp(_options: CoveoSchema): Rule {
const packageJson = JSON.parse(packageJsonBuffer.toString());

packageJson.scripts['start'] =
'concurrently "npm run start-server" "ng serve"';
'concurrently --raw "npm run start-server" "ng serve"';
packageJson.scripts['start-server'] = 'node ./scripts/start-server.js';

tree.overwrite(
Expand Down
82 changes: 70 additions & 12 deletions packages/cli-e2e/__tests__/angular.specs.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import retry from 'async-retry';

import type {ChildProcessWithoutNullStreams} from 'child_process';
import type {HTTPRequest, Browser, Page} from 'puppeteer';

import {setupUIProject, teardownUIProject} from '../utils/cli';
import {getNewBrowser} from '../utils/browser';
import {
answerPrompt,
getProjectPath,
isGenericYesNoPrompt,
setupUIProject,
} from '../utils/cli';
import {captureScreenshots, getNewBrowser, openNewPage} from '../utils/browser';
import {isSearchRequest} from '../utils/platform';
import {EOL} from 'os';
import stripAnsi from 'strip-ansi';
import {ProcessManager} from '../utils/processManager';

describe('ui', () => {
describe('create:angular', () => {
let browser: Browser;
const cliProcesses: ChildProcessWithoutNullStreams[] = [];
let processManager: ProcessManager;
// TODO: CDX-90: Assign a dynamic port for the search token server on all ui projects
const clientPort = '4200';
const projectName = 'angular-project';
Expand All @@ -20,29 +27,76 @@ describe('ui', () => {
let page: Page;

beforeAll(async () => {
processManager = new ProcessManager();
browser = await getNewBrowser();
await setupUIProject('ui:create:angular', projectName, cliProcesses, {
flags: ['--defaults'],
timeout: 40e3,
const buildProcess = setupUIProject(
processManager,
'ui:create:angular',
projectName,
{
flags: ['--defaults'],
}
);

buildProcess.stdout.on('data', async (data) => {
if (isGenericYesNoPrompt(data.toString())) {
await answerPrompt(`y${EOL}`, buildProcess);
}
});
}, 3e6);

await Promise.race([
new Promise<void>((resolve) => {
buildProcess.on('exit', async () => {
resolve();
});
}),
new Promise<void>((resolve) => {
buildProcess.stdout.on('data', (data) => {
if (
/Happy hacking !/.test(
stripAnsi(data.toString()).replace(/\n/g, '')
)
) {
resolve();
}
});
}),
]);

const startServerProcess = processManager.spawn('npm', ['run', 'start'], {
cwd: getProjectPath(projectName),
});

await new Promise<void>((resolve) => {
startServerProcess.stdout.on('data', async (data) => {
if (
/Compiled successfully/.test(
stripAnsi(data.toString()).replace(/\n/g, '')
)
) {
resolve();
}
});
});
}, 420e3);

beforeEach(async () => {
page = await browser.newPage();
page = await openNewPage(browser, page);

page.on('request', (request: HTTPRequest) => {
interceptedRequests.push(request);
});
});

afterEach(async () => {
await captureScreenshots(browser);
page.removeAllListeners('request');
interceptedRequests = [];
});

afterAll(async () => {
await browser.close();
await teardownUIProject(cliProcesses);
await processManager.killAllProcesses();
}, 5e3);

it('should contain a search page section', async () => {
Expand All @@ -54,9 +108,13 @@ describe('ui', () => {
});

it('should retrieve the search token on the page load', async () => {
const tokenResponseListener = page.waitForResponse(tokenProxyEndpoint);

page.goto(searchPageEndpoint);
const tokenResponse = await page.waitForResponse(tokenProxyEndpoint);
expect(JSON.parse(await tokenResponse.text())).toMatchObject({

expect(
JSON.parse(await (await tokenResponseListener).text())
).toMatchObject({
token: expect.stringMatching(/^eyJhb.+/),
});
});
Expand Down
20 changes: 9 additions & 11 deletions packages/cli-e2e/__tests__/auth.specs.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
import {spawn} from 'child_process';
import retry from 'async-retry';

import type {Browser} from 'puppeteer';
import type {ChildProcessWithoutNullStreams} from 'child_process';

import {
answerPrompt,
CLI_EXEC_PATH,
isYesNoPrompt,
killCliProcess,
} from '../utils/cli';
import {answerPrompt, CLI_EXEC_PATH, isYesNoPrompt} from '../utils/cli';
import {captureScreenshots, connectToChromeBrowser} from '../utils/browser';
import {ProcessManager} from '../utils/processManager';

describe('auth', () => {
describe('login', () => {
let browser: Browser;
let cliProcess: ChildProcessWithoutNullStreams;
let processManager: ProcessManager;

beforeAll(async () => {
browser = await connectToChromeBrowser();
processManager = new ProcessManager();
});

afterEach(async () => {
await captureScreenshots(browser);
await killCliProcess(cliProcess);
await processManager.killAllProcesses();
}, 5e3);

it('should open the platform page', async () => {
// TODO CDX-98: Remove `-e=dev`.
cliProcess = spawn(CLI_EXEC_PATH, ['auth:login', '-e=dev']);
const cliProcess = processManager.spawn(CLI_EXEC_PATH, [
'auth:login',
'-e=dev',
]);
cliProcess.stderr.on('data', async (data) => {
if (isYesNoPrompt(data.toString())) {
await answerPrompt('n', cliProcess);
Expand Down
45 changes: 35 additions & 10 deletions packages/cli-e2e/__tests__/react.specs.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import retry from 'async-retry';

import type {ChildProcessWithoutNullStreams} from 'child_process';
import type {HTTPRequest, Browser, Page} from 'puppeteer';
import stripAnsi from 'strip-ansi';

import {setupUIProject, teardownUIProject} from '../utils/cli';
import {getNewBrowser} from '../utils/browser';
import {captureScreenshots, getNewBrowser, openNewPage} from '../utils/browser';
import {getProjectPath, setupUIProject} from '../utils/cli';
import {isSearchRequest} from '../utils/platform';
import {ProcessManager} from '../utils/processManager';

describe('ui', () => {
describe('create:react', () => {
let browser: Browser;
const cliProcesses: ChildProcessWithoutNullStreams[] = [];
let processManager: ProcessManager;
// TODO: CDX-90: Assign a dynamic port for the search token server on all ui projects
const clientPort = '3000';
const projectName = 'react-project';
Expand All @@ -21,27 +22,51 @@ describe('ui', () => {

beforeAll(async () => {
browser = await getNewBrowser();
await setupUIProject('ui:create:react', projectName, cliProcesses, {
timeout: 30e3,
processManager = new ProcessManager();
const buildProcess = setupUIProject(
processManager,
'ui:create:react',
projectName
);

await new Promise<void>((resolve) => {
buildProcess.on('exit', async () => {
resolve();
});
});
}, 3e6);

beforeEach(async () => {
page = await browser.newPage();
const startServerProcess = processManager.spawn('npm', ['run', 'start'], {
cwd: getProjectPath(projectName),
});
await new Promise<void>((resolve) => {
startServerProcess.stdout.on('data', async (data) => {
if (
/You can now view react-project in the browser/.test(
stripAnsi(data.toString()).replace(/\n/g, '')
)
) {
resolve();
}
});
});
}, 15 * 60e3);

beforeEach(async () => {
page = await openNewPage(browser, page);
page.on('request', (request: HTTPRequest) => {
interceptedRequests.push(request);
});
});

afterEach(async () => {
await captureScreenshots(browser);
page.removeAllListeners('request');
interceptedRequests = [];
});

afterAll(async () => {
await browser.close();
await teardownUIProject(cliProcesses);
await processManager.killAllProcesses();
}, 5e3);

it('should contain a search page section', async () => {
Expand Down
Loading

0 comments on commit 37d119b

Please sign in to comment.