Skip to content

Commit

Permalink
[Code] functional test for code intelligence (#31673)
Browse files Browse the repository at this point in the history
  • Loading branch information
mw-ding authored Feb 23, 2019
1 parent 9519432 commit 821e47b
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 5 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/code/public/components/hover/hover_buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ export class HoverButtons extends React.PureComponent<HoverButtonProps> {
size="s"
isDisabled={this.props.state !== HoverState.READY}
onClick={this.props.gotoDefinition}
data-test-subj="codeGoToDefinitionButton"
>
Goto Definition
</EuiButton>
<EuiButton
size="s"
isDisabled={this.props.state !== HoverState.READY}
onClick={this.props.findReferences}
data-test-subj="codeFindReferenceButton"
>
Find Reference
</EuiButton>
Expand Down
228 changes: 228 additions & 0 deletions x-pack/test/functional/apps/code/code_intelligence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import expect from 'expect.js';
import { TestInvoker } from './lib/types';

// tslint:disable:no-default-export
export default function codeIntelligenceFunctonalTests({
getService,
getPageObjects,
}: TestInvoker) {
// const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const retry = getService('retry');
const log = getService('log');
const browser = getService('browser');
const find = getService('find');
const config = getService('config');
const FIND_TIME = config.get('timeouts.find');
const PageObjects = getPageObjects(['common', 'header', 'security', 'code', 'home']);

describe('Code', () => {
describe('Code intelligence in source view page', () => {
const repositoryListSelector = 'codeRepositoryList codeRepositoryItem';

before(async () => {
// Navigate to the code app.
await PageObjects.common.navigateToApp('code');
await PageObjects.header.waitUntilLoadingHasFinished();

// Prepare a git repository for the test
await PageObjects.code.fillImportRepositoryUrlInputBox(
'https://github.com/Microsoft/TypeScript-Node-Starter'
);
// Click the import repository button.
await PageObjects.code.clickImportRepositoryButton();

await retry.tryForTime(300000, async () => {
const repositoryItems = await testSubjects.findAll(repositoryListSelector);
expect(repositoryItems).to.have.length(1);
expect(await repositoryItems[0].getVisibleText()).to.equal(
'Microsoft/TypeScript-Node-Starter'
);

// Wait for the repository to finish index.
expect(await testSubjects.exists('repositoryIndexDone')).to.be(true);
});
});

after(async () => {
// Navigate to the code app.
await PageObjects.common.navigateToApp('code');
await PageObjects.header.waitUntilLoadingHasFinished();

// Clean up the imported repository
await PageObjects.code.clickDeleteRepositoryButton();
await retry.try(async () => {
const repositoryItems = await testSubjects.findAll(repositoryListSelector);
expect(repositoryItems).to.have.length(0);
});

await PageObjects.security.logout();
});

beforeEach(async () => {
// Navigate to the code app.
await PageObjects.common.navigateToApp('code');
await PageObjects.header.waitUntilLoadingHasFinished();

// Enter the first repository from the admin page.
await testSubjects.click(repositoryListSelector);
});

it('Hover on a reference and jump to definition across file', async () => {
log.debug('Hover on a reference and jump to definition across file');

// Visit the /src/controllers/user.ts file
// Wait the file tree to be rendered and click the 'src' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src')).to.be(true);
});

await testSubjects.click('codeFileTreeNode-Directory-src');
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src/controllers')).to.be(
true
);
});

await testSubjects.click('codeFileTreeNode-Directory-src/controllers');
// Then the 'controllers' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-File-src/controllers/user.ts')).to.be(
true
);
});

await testSubjects.click('codeFileTreeNode-File-src/controllers/user.ts');
// Then the 'user.ts' file on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
});

// Hover on the 'UserModel' reference on line 5.
await retry.try(async () => {
const spans = await find.allByCssSelector('.mtk31', FIND_TIME);
expect(spans.length).to.greaterThan(1);
const userModelSpan = spans[1];
expect(await userModelSpan.getVisibleText()).to.equal('UserModel');
await browser.moveMouseTo(userModelSpan);
// Expect the go to defintion button show up eventually.
expect(await testSubjects.exists('codeGoToDefinitionButton')).to.be(true);
});

await testSubjects.click('codeGoToDefinitionButton');
await retry.tryForTime(30000, async () => {
const currentUrl: string = await browser.getCurrentUrl();
// Expect to jump to src/models/User.ts file on line 5.
expect(currentUrl.indexOf('src/models/User.ts!L5:13')).to.greaterThan(0);
});
});

it('Find references and jump to reference', async () => {
log.debug('Find references and jump to reference');

// Visit the /src/models/User.ts file
// Wait the file tree to be rendered and click the 'src' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src')).to.be(true);
});

await testSubjects.click('codeFileTreeNode-Directory-src');
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src/models')).to.be(true);
});

await testSubjects.click('codeFileTreeNode-Directory-src/models');
// Then the 'models' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-File-src/models/User.ts')).to.be(true);
});

await testSubjects.click('codeFileTreeNode-File-src/models/User.ts');
// Then the 'User.ts' file on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
});

// Hover on the 'UserModel' reference on line 5.
await retry.try(async () => {
const spans = await find.allByCssSelector('.mtk31', FIND_TIME);
expect(spans.length).to.greaterThan(1);
const userModelSpan = spans[0];
expect(await userModelSpan.getVisibleText()).to.equal('UserModel');
await browser.moveMouseTo(userModelSpan);
// Expect the go to defintion button show up eventually.
expect(await testSubjects.exists('codeFindReferenceButton')).to.be(true);
});

await testSubjects.click('codeFindReferenceButton');
await retry.tryForTime(30000, async () => {
// Expect the find references panel show up and having highlights.
const spans = await find.allByCssSelector('.code-search-highlight', FIND_TIME);
expect(spans.length).to.greaterThan(0);
const firstReference = spans[0];
await firstReference.click();
const currentUrl: string = await browser.getCurrentUrl();
// Expect to jump to src/controllers/user.ts file on line 42.
expect(currentUrl.indexOf('src/controllers/user.ts!L42:0')).to.greaterThan(0);
});
});

it('Hover on a reference and jump to a different repository', async () => {
log.debug('Hover on a reference and jump to a different repository');

// Visit the /src/controllers/user.ts file
// Wait the file tree to be rendered and click the 'src' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src')).to.be(true);
});

await testSubjects.click('codeFileTreeNode-Directory-src');
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-Directory-src/controllers')).to.be(
true
);
});

await testSubjects.click('codeFileTreeNode-Directory-src/controllers');
// Then the 'controllers' folder on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeFileTreeNode-File-src/controllers/user.ts')).to.be(
true
);
});

await testSubjects.click('codeFileTreeNode-File-src/controllers/user.ts');
// Then the 'user.ts' file on the file tree.
await retry.try(async () => {
expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
});

// Hover on the 'async' reference on line 1.
await retry.try(async () => {
const spans = await find.allByCssSelector('.mtk17', FIND_TIME);
expect(spans.length).to.greaterThan(1);
const asyncSpan = spans[1];
expect(await asyncSpan.getVisibleText()).to.equal('async');
await browser.moveMouseTo(asyncSpan);
// Expect the go to defintion button show up eventually.
expect(await testSubjects.exists('codeGoToDefinitionButton')).to.be(true);
});

await testSubjects.click('codeGoToDefinitionButton');
await retry.tryForTime(30000, async () => {
const currentUrl: string = await browser.getCurrentUrl();
// Expect to jump to repository github.com/DefinitelyTyped/DefinitelyTyped.
expect(currentUrl.indexOf('github.com/DefinitelyTyped/DefinitelyTyped')).to.greaterThan(
0
);
});
});
});
});
}
2 changes: 1 addition & 1 deletion x-pack/test/functional/apps/code/explore_repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import expect from 'expect.js';
import { TestInvoker } from './lib/types';

// tslint:disable:no-default-export
export default function manageRepositoriesFunctonalTests({
export default function exploreRepositoryFunctonalTests({
getService,
getPageObjects,
}: TestInvoker) {
Expand Down
1 change: 1 addition & 0 deletions x-pack/test/functional/apps/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export default function codeApp({ loadTestFile }: TestInvoker) {
loadTestFile(require.resolve('./manage_repositories'));
loadTestFile(require.resolve('./search'));
loadTestFile(require.resolve('./explore_repository'));
loadTestFile(require.resolve('./code_intelligence'));
});
}
5 changes: 1 addition & 4 deletions x-pack/test/functional/apps/code/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import expect from 'expect.js';
import { TestInvoker } from './lib/types';

// tslint:disable:no-default-export
export default function manageRepositoriesFunctonalTests({
getService,
getPageObjects,
}: TestInvoker) {
export default function searchFunctonalTests({ getService, getPageObjects }: TestInvoker) {
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const retry = getService('retry');
Expand Down

0 comments on commit 821e47b

Please sign in to comment.