Setup initial e2e tests with Spectron.
This commit is contained in:
Родитель
b345a01b1c
Коммит
6107406bbb
|
@ -9,3 +9,4 @@ custom-botframework-webchat/dist
|
|||
coverage
|
||||
build/
|
||||
.vscode/*
|
||||
chrome-driver-log.txt
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"name": "Jest Current File",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
||||
"args": [
|
||||
"${relativeFile}",
|
||||
"${fileBasename}",
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
|
|
|
@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## Unreleased
|
||||
|
||||
## Added
|
||||
- [main] Added End-to-End tests using Spectron in PR [1696](https://github.com/microsoft/BotFramework-Emulator/pull/1696)
|
||||
|
||||
## v4.5.2 - 2019 - 07 - 17
|
||||
## Fixed
|
||||
- [client] Fixed some minor styling issues with the JSON inspector in PR [1691](https://github.com/microsoft/BotFramework-Emulator/pull/1691)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,8 +7,9 @@
|
|||
"rebuild:keytar:electron": "rimraf node_modules/keytar/build && electron-rebuild",
|
||||
"rebuild:keytar:node": "npm rebuild keytar",
|
||||
"start": "cd packages\\app\\client && npm run start",
|
||||
"test": "npm run rebuild:keytar:node && jest --no-cache --runInBand",
|
||||
"test": "npm run rebuild:keytar:node && jest --no-cache --runInBand --testPathIgnorePatterns=/packages/app/main/e2e/",
|
||||
"test:coveralls": "jest --runInBand --coverage --coverageReporters=text-lcov | coveralls",
|
||||
"test:e2e": "npm run rebuild:keytar:electron && jest --no-cache --runInBand --testPathPattern=/e2e/.*\\.spec\\.ts$",
|
||||
"test:gen-lcov": "npm run test -- --coverage --coverageReporters=lcov --coverageReporters=text",
|
||||
"uploadcoverage": "cat ./coverage/lcov.info | coveralls"
|
||||
},
|
||||
|
|
|
@ -115,6 +115,7 @@ export class BotCreationDialog extends React.Component<{}, BotCreationDialogStat
|
|||
onChange={this.onInputChange}
|
||||
label={'Bot name'}
|
||||
required={true}
|
||||
name={'create-bot-name'}
|
||||
/>
|
||||
<TextField
|
||||
onChange={this.onInputChange}
|
||||
|
@ -123,6 +124,7 @@ export class BotCreationDialog extends React.Component<{}, BotCreationDialogStat
|
|||
label={'Endpoint URL'}
|
||||
required={true}
|
||||
value={this.state.endpoint.endpoint}
|
||||
name={'create-bot-url'}
|
||||
/>
|
||||
{endpointWarning && <span className={styles.endpointWarning}>{endpointWarning}</span>}
|
||||
<Row className={styles.multiInputRow}>
|
||||
|
@ -199,7 +201,12 @@ export class BotCreationDialog extends React.Component<{}, BotCreationDialogStat
|
|||
|
||||
<DialogFooter>
|
||||
<DefaultButton text="Cancel" onClick={this.onCancel} />
|
||||
<PrimaryButton text="Save and connect" onClick={this.onSaveAndConnect} disabled={!requiredFieldsCompleted} />
|
||||
<PrimaryButton
|
||||
text="Save and connect"
|
||||
onClick={this.onSaveAndConnect}
|
||||
disabled={!requiredFieldsCompleted}
|
||||
name={'create-bot-save'}
|
||||
/>
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
@ -133,7 +133,7 @@ export class OpenBotDialog extends Component<OpenBotDialogProps, OpenBotDialogSt
|
|||
|
||||
return (
|
||||
<Dialog cancel={this.props.onDialogCancel} className={openBotStyles.themeOverrides} title="Open a bot">
|
||||
<form onSubmit={this.onSubmit}>
|
||||
<form id="open-bot-dialog" onSubmit={this.onSubmit}>
|
||||
<div className={openBotStyles.autoCompleteBar}>
|
||||
<AutoComplete
|
||||
autoFocus={true}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Framework Emulator Github:
|
||||
// https://github.com/Microsoft/BotFramwork-Emulator
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
|
||||
import { existsSync, unlinkSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { Application } from 'spectron';
|
||||
|
||||
import { appPath, chromeDriverLogPath, electronPath } from './utils';
|
||||
import { init, setupMock } from './mocks/electronDialog';
|
||||
|
||||
describe('Creating a bot', () => {
|
||||
let app: Application;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.setTimeout(30000);
|
||||
app = new Application({
|
||||
path: electronPath,
|
||||
args: [appPath],
|
||||
chromeDriverLogPath,
|
||||
});
|
||||
init(app);
|
||||
await app.start();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (app && app.isRunning()) {
|
||||
await app.stop();
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: could be made more comprehensive by checking that the bot was added to MRU
|
||||
// on welcome page
|
||||
it('should create a bot', async () => {
|
||||
// open the create bot modal
|
||||
const ctaLinks = await app.client.$$('button[class*="cta-link"]');
|
||||
const createBotLink = ctaLinks[0];
|
||||
await app.client.elementIdClick(createBotLink.ELEMENT);
|
||||
|
||||
// fill out the bot name and endpoint
|
||||
await app.client.setValue('input[name="create-bot-name"]', 'e2e-test-bot');
|
||||
await app.client.setValue('input[name="create-bot-url"]', 'http://localhost:3978/api/messages');
|
||||
|
||||
// mock the result from the save dialog
|
||||
const tempPath = await app.electron.remote.app.getPath('temp');
|
||||
const testBotPath = join(tempPath, 'e2e-test-bot.bot');
|
||||
await setupMock(app, { method: 'showSaveDialog', value: testBotPath });
|
||||
|
||||
// click save
|
||||
await app.client.click('button[name="create-bot-save"]');
|
||||
|
||||
// wait for Web Chat to show up
|
||||
await app.client.waitForExist('div[role="log"] + div[role="form"]', 2000);
|
||||
|
||||
// verify that the bot was written to disk
|
||||
expect(existsSync(testBotPath)).toBe(true);
|
||||
|
||||
// delete the bot from disk
|
||||
unlinkSync(testBotPath);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Framework Emulator Github:
|
||||
// https://github.com/Microsoft/BotFramwork-Emulator
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
import { join } from 'path';
|
||||
|
||||
import { Application } from 'spectron';
|
||||
|
||||
type ElectronDialogMethod =
|
||||
| 'showOpenDialog'
|
||||
| 'showSaveDialog'
|
||||
| 'showMessageBox'
|
||||
| 'showErrorBox'
|
||||
| 'showCertificateTrustDialog';
|
||||
|
||||
// make spectron load the preload script first
|
||||
export function init(app: Application & { args?: string[] }) {
|
||||
if (app.args && app.args.length) {
|
||||
// args: [appPath] -> [-r, dialogMock, appPath]
|
||||
app.args.unshift(join(__dirname, 'electronDialogPreload.js'));
|
||||
app.args.unshift('-r');
|
||||
}
|
||||
}
|
||||
|
||||
// setup an electron.dialog mock
|
||||
export function setupMock(app: Application, options: { method: ElectronDialogMethod; value: any }): Promise<any> {
|
||||
if (app) {
|
||||
return app.electron.ipcRenderer.sendSync('SPECTRON/SETUP_DIALOG_MOCK', options);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Framework Emulator Github:
|
||||
// https://github.com/Microsoft/BotFramwork-Emulator
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
const { dialog, ipcMain } = require('electron');
|
||||
|
||||
// options: { method: string, value: string | string[] }
|
||||
function mockDialogFunction(options) {
|
||||
if (options.method && options.value) {
|
||||
dialog[options.method] = function() {
|
||||
return new Promise(resolve => {
|
||||
resolve(options.value);
|
||||
});
|
||||
};
|
||||
} else {
|
||||
throw new Error('Options missing method or value keys.');
|
||||
}
|
||||
}
|
||||
|
||||
// register a listener that can be called into from test
|
||||
ipcMain.on('SPECTRON/SETUP_DIALOG_MOCK', (e, options) => {
|
||||
mockDialogFunction(options);
|
||||
e.returnValue = true;
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Framework Emulator Github:
|
||||
// https://github.com/Microsoft/BotFramwork-Emulator
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
|
||||
import { Application } from 'spectron';
|
||||
|
||||
import { appPath, chromeDriverLogPath, electronPath } from './utils';
|
||||
|
||||
describe('Starting up the Emulator', () => {
|
||||
let app: Application;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.setTimeout(30000);
|
||||
app = new Application({
|
||||
path: electronPath,
|
||||
args: [appPath],
|
||||
chromeDriverLogPath,
|
||||
});
|
||||
await app.start();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (app && app.isRunning()) {
|
||||
await app.stop();
|
||||
}
|
||||
});
|
||||
|
||||
it('should show an initial window', async () => {
|
||||
const count = await app.client.getWindowCount();
|
||||
expect(count).toBe(1);
|
||||
expect(await app.browserWindow.getTitle()).toBe('Bot Framework Emulator');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Framework Emulator Github:
|
||||
// https://github.com/Microsoft/BotFramwork-Emulator
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
import { join } from 'path';
|
||||
|
||||
export const electronPath =
|
||||
process.platform === 'win32'
|
||||
? join(__dirname, '..', 'node_modules', '.bin', 'electron.cmd')
|
||||
: join(__dirname, '..', 'node_modules', '.bin', 'electron');
|
||||
|
||||
export const appPath = join(__dirname, '..', 'app', 'server', 'main.js');
|
||||
|
||||
export const chromeDriverLogPath = join(__dirname, 'chrome-driver-log.txt');
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -115,6 +115,7 @@
|
|||
"ncp": "^2.0.0",
|
||||
"nodemon": "1.18.11",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"spectron": "^6.0.0",
|
||||
"through2": "^2.0.3",
|
||||
"typescript": "3.1.1",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
|
|
|
@ -278,7 +278,9 @@ class EmulatorApplication {
|
|||
|
||||
this.mainWindow = new Window(this.mainBrowserWindow);
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
SplashScreen.show(this.mainBrowserWindow);
|
||||
}
|
||||
const page =
|
||||
process.env.ELECTRON_TARGET_URL ||
|
||||
url.format({
|
||||
|
|
Загрузка…
Ссылка в новой задаче