Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate E2E test with bot creation v2 #7040

Merged
merged 10 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 8 additions & 26 deletions Composer/cypress/integration/Breadcrumb.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@

context('breadcrumb', () => {
beforeEach(() => {
cy.visit('/home');
cy.createBot('TodoSample');

// Return to Main.dialog
cy.findByTestId('ProjectTree').within(() => {
cy.findAllByText('__TestTodoSample').last().click();
cy.createTestBot('EmptySample', ({ id }) => {
cy.visit(`/bot/${id}`);
});
});

Expand All @@ -23,30 +19,16 @@ context('breadcrumb', () => {
});
}

it('can show dialog name in breadcrumb', () => {
it('can show dialog, trigger, action in breadcrumb', () => {
// Should path = main dialog at first render
hasBreadcrumbItems(cy, ['__TestTodoSample']);
hasBreadcrumbItems(cy, ['TestBot_EmptySample']);

// Return to Main.dialog
// Click on an trigger
cy.findByTestId('ProjectTree').within(() => {
cy.findAllByText('__TestTodoSample').last().click();
cy.findAllByText('Greeting').last().click();
});

hasBreadcrumbItems(cy, ['__TestTodoSample']);
});

it('can show dialog and trigger name in breadcrumb', () => {
cy.findByTestId('ProjectTree').within(() => {
cy.findByTestId('addtodo_Dialog started').click();
});

hasBreadcrumbItems(cy, ['addtodo', 'Dialog started']);
});

it('can show action name in breadcrumb', () => {
cy.findByTestId('ProjectTree').within(() => {
cy.findByText('Greeting').click();
});
hasBreadcrumbItems(cy, ['TestBot_EmptySample', 'Greeting']);

// Click on an action
cy.withinEditor('VisualEditor', () => {
Expand All @@ -55,6 +37,6 @@ context('breadcrumb', () => {
});
});

hasBreadcrumbItems(cy, ['__TestTodoSample', 'Greeting', 'Send a response']);
hasBreadcrumbItems(cy, ['TestBot_EmptySample', 'Greeting', 'Send a response']);
});
});
9 changes: 5 additions & 4 deletions Composer/cypress/integration/LGPage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

context('LG Page', () => {
beforeEach(() => {
cy.visit('/home');
cy.createBot('TodoSample');
cy.createTestBot('EmptySample', ({ id }) => {
cy.visit(`/bot/${id}`);
});
});

it('can open language generation page', () => {
cy.findByTestId('LeftNav-CommandBarButtonBot responses').click();
// left nav tree
cy.contains('TodoSample');
cy.contains('TestBot_EmptySample');

cy.findByTestId('showcode').as('switchButton');

Expand All @@ -28,7 +29,7 @@ context('LG Page', () => {

// nav to Main dialog
cy.findByTestId('ProjectTree').within(() => {
cy.findAllByText('__TestTodoSample').last().click();
cy.findAllByText('TestBot_EmptySample').last().click();
});
});
});
11 changes: 5 additions & 6 deletions Composer/cypress/integration/LUPage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@

context('LU Page', () => {
beforeEach(() => {
cy.visit('/home');
cy.createBot('ToDoBotWithLuisSample');
cy.createTestBot('EmptySample', ({ id }) => {
cy.visit(`/bot/${id}`);
});
});

it('can open language understanding page', () => {
cy.findByTestId('LeftNav-CommandBarButtonUser input').click();
// left nav tree
cy.contains('__TestToDoBotWithLuisSample');

cy.findByTestId('showcode').should('not.exist');
cy.contains('TestBot_EmptySample');

// by default it goes to table view
cy.findByTestId('LUPage').findByTestId('table-view').should('exist');
Expand All @@ -22,7 +21,7 @@ context('LU Page', () => {

// nav to ToDoBotWithLuisSample.main dialog
cy.findByTestId('ProjectTree').within(() => {
cy.findAllByText('__TestToDoBotWithLuisSample').last().click('left');
cy.findAllByText('TestBot_EmptySample').last().click();
});
cy.findByTestId('showcode').as('switchButton');
// goto edit-mode
Expand Down
18 changes: 18 additions & 0 deletions Composer/cypress/support/commands.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ declare namespace Cypress {
*/
createBot(botId: string, botName?: string): void;

/**
* Creates a bot based on empty bot.
* @example cy.createBot('EmptySample', ()=> {})
*/
createBotV2(botName: string, createdCallback: (bot: any) => void): void;

/**
* Creates a bot based on empty bot.
* @example cy.createTemplateBot('EmptySample', ()=> {})
*/
createTemplateBot(botName: string, createdCallback: (bot: any) => void): void;

/**
* Creates a bot from above created template bot.
* @example cy.createTestBot('EmptySample', ()=> {})
*/
createTestBot(botName: string, createdCallback: (bot: any) => void): void;

/**
* Visits a page from the left nav bar using the page's testid
* @example visitPage('Bot Responses');
Expand Down
61 changes: 61 additions & 0 deletions Composer/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import '@testing-library/cypress/add-commands';

let TemplateBotProjectId = '';

Cypress.Commands.add('createBot', (botId: string, botName?: string) => {
const name = `__Test${botName || botId}`;

Expand All @@ -19,6 +21,65 @@ Cypress.Commands.add('createBot', (botId: string, botName?: string) => {
});
});

Cypress.Commands.add('createBotV2', (botName: string, callback: (bot: any) => void) => {
const params = {
description: '',
location: '',
name: botName,
runtimeLanguage: 'dotnet',
runtimeType: 'webapp',
schemaUrl: '',
storageId: 'default',
templateId: '@microsoft/generator-bot-empty',
templateVersion: '1.0.0-rc3',
};

const pollingRequestBotStatus = (jobId: string, callback: (result: any) => void) => {
cy.wait(2000);
try {
cy.request('get', `/api/status/${jobId}`).then((res) => {
const { httpStatusCode, id, result } = res.body;
if (httpStatusCode !== 200) {
pollingRequestBotStatus(id, callback);
} else {
callback(result);
}
});
} catch (error) {
pollingRequestBotStatus(jobId, callback);
}
};

cy.request('post', '/api/v2/projects', params).then((res) => {
const { jobId } = res.body;
// install package can take a long time.
cy.wait(20000);
pollingRequestBotStatus(jobId, (result) => callback(result));
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should cache the result of the first creation and the use that bot as a template by copying files and performing and transforms on the files. I know we don't use this api in too many places, but I think it's worth investing in the performance here to not slow the e2e execution down significantly.

Copy link
Contributor Author

@zhixzhan zhixzhan Apr 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @a-b-r-o-w-n , I made some updates, before all spec start, will create a template bot. when execute each spec, will use it call save as API, and spec will get a new test bot.


Cypress.Commands.add('createTemplateBot', (botName: string, callback: (bot: any) => void) => {
cy.createBotV2(`TemplateBot_${botName}`, (bot) => {
TemplateBotProjectId = bot.id;
});
});

Cypress.Commands.add('createTestBot', (botName: string, callback: (bot: any) => void) => {
const name = `TestBot_${botName}`;
zhixzhan marked this conversation as resolved.
Show resolved Hide resolved

const params = {
description: '',
location: '/Users/yellowglue/Projects/BotFramework-Composer/MyBotsTest',
name,
storageId: 'default',
};

cy.request('post', `/api/projects/${TemplateBotProjectId}/project/saveAs`, params).then((res) => {
const bot = res.body;
callback(bot);
});
});

Cypress.Commands.add('withinEditor', (editorName, cb) => {
cy.findByTestId(editorName).within(cb);
});
Expand Down
9 changes: 8 additions & 1 deletion Composer/cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

import './commands';

before(() => {
cy.exec('yarn test:integration:clean-all');
cy.createTemplateBot('EmptySample', ({ id }) => {
cy.visit(`/bot/${id}`);
});
});

beforeEach(() => {
cy.exec('yarn test:integration:clean');
window.localStorage.setItem('composer:userSettings', JSON.stringify({ telemetry: { allowDataCollection: false } }));
Expand All @@ -13,5 +20,5 @@ beforeEach(() => {
after(() => {
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(500);
cy.exec('yarn test:integration:clean');
cy.exec('yarn test:integration:clean-all');
});
1 change: 1 addition & 0 deletions Composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"test:integration:start-server": "node scripts/e2e.js",
"test:integration:open": "cypress open",
"test:integration:clean": "node scripts/clean-e2e.js",
"test:integration:clean-all": "node scripts/clean-e2e.js --all",
"lint": "wsrun --exclude-missing --collect-logs --report lint",
"lint:ci": "wsrun --exclude-missing --collect-logs --report --no-prefix lint --format github-actions",
"lint:fix": "wsrun --exclude-missing --collect-logs --report lint:fix",
Expand Down
4 changes: 3 additions & 1 deletion Composer/scripts/clean-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const rootDir = path.resolve(__dirname, '..');
const BOTS_DIR = process.env.COMPOSER_BOTS_FOLDER || path.resolve(rootDir, 'cypress/__test_bots__');
const APP_DATA = process.env.COMPOSER_APP_DATA || path.resolve(rootDir, 'cypress/__e2e_data.json');

const cleanAll = process.argv.indexOf('--all') !== -1;

function cleanup() {
try {
rimraf.sync(BOTS_DIR);
rimraf.sync(path.join(BOTS_DIR, cleanAll ? '**' : 'TestBot_**'));
} catch {
// do nothing
}
Expand Down