| Index: dashboard/dashboard/elements/test-picker.html
|
| diff --git a/dashboard/dashboard/elements/test-picker.html b/dashboard/dashboard/elements/test-picker.html
|
| index 770e073a41ac9a369c9659ca24f0feec0c604d5e..139bf073f84bb9c8ba15a98bf3f801c373d5f986 100644
|
| --- a/dashboard/dashboard/elements/test-picker.html
|
| +++ b/dashboard/dashboard/elements/test-picker.html
|
| @@ -13,6 +13,8 @@ found in the LICENSE file.
|
| <link rel="import" href="/dashboard/elements/autocomplete-box.html">
|
| <link rel="import" href="/dashboard/static/simple_xhr.html">
|
|
|
| +<link rel="import" href="/tracing/base/base.html">
|
| +
|
| <dom-module id="test-picker">
|
| <template>
|
| <style include="iron-flex iron-flex-alignment">
|
| @@ -101,6 +103,48 @@ found in the LICENSE file.
|
| <script>
|
| 'use strict';
|
|
|
| + // TODO(eakuefner): https://github.com/catapult-project/catapult/issues/3441
|
| + tr.exportTo('d', function() {
|
| + class Subtests {
|
| + constructor() {
|
| + this.subtests_ = new Map();
|
| + }
|
| +
|
| + // TODO(eakuefner): implemement cancellation by wrapping
|
| + async getSubtestsForPath(path) {
|
| + if (this.subtests_.has(path)) {
|
| + return await this.subtests_.get(path);
|
| + }
|
| +
|
| + const params = {
|
| + type: 'pattern'
|
| + };
|
| + params.p = `${path}/*`;
|
| + const fullSubtests = await simple_xhr.asPromise(
|
| + '/list_tests', params);
|
| + // TODO(eakuefner): Standardize logic for dealing with test paths on
|
| + // the client side. See
|
| + // https://github.com/catapult-project/catapult/issues/3443.
|
| + const subtests = [];
|
| + for (const fullSubtest of fullSubtests) {
|
| + subtests.push({
|
| + name: fullSubtest.substring(fullSubtest.lastIndexOf('/') + 1)});
|
| + }
|
| +
|
| + this.subtests_[path] = subtests;
|
| + return subtests;
|
| + }
|
| +
|
| + prepopulate(obj) {
|
| + for (const [path, subtests] of obj) {
|
| + this.subtests_.set(path, Promise.resolve(subtests));
|
| + }
|
| + }
|
| + }
|
| +
|
| + return {Subtests};
|
| + });
|
| +
|
| Polymer({
|
|
|
| is: 'test-picker',
|
| @@ -154,6 +198,11 @@ found in the LICENSE file.
|
| ])
|
| },
|
|
|
| + subtests: {
|
| + type: Object,
|
| + value: () => new d.Subtests()
|
| + },
|
| +
|
| xsrfToken: { notify: true }
|
|
|
| },
|
| @@ -253,8 +302,6 @@ found in the LICENSE file.
|
| } else if (boxIndex == 0) {
|
| this.updateTestSuiteDescription();
|
| this.updateBotMenu();
|
| - } else if (boxIndex == 1) {
|
| - this.sendSubtestRequest();
|
| } else {
|
| // Update all the next dropdown menus for subtests.
|
| this.updateSubtestMenus(boxIndex + 1);
|
| @@ -288,10 +335,9 @@ found in the LICENSE file.
|
| var botItems = this.getBotItems();
|
| menu.set('items', botItems);
|
| menu.set('disabled', botItems.length === 0);
|
| - this.subtestDict = null;
|
| - // If there's a selection, send a subtest request.
|
| + // If there's a selection, update the subtest menus.
|
| if (menu.selectedItem) {
|
| - this.sendSubtestRequest();
|
| + this.updateSubtestMenus(2);
|
| } else {
|
| // Clear all subtest menus.
|
| this.splice('selectionModels', 2);
|
| @@ -300,84 +346,43 @@ found in the LICENSE file.
|
| },
|
|
|
| /**
|
| - * Sends a request for subtestDict base on selected test suite and bot.
|
| - */
|
| - sendSubtestRequest: function() {
|
| - if (this.subtestXhr) {
|
| - this.subtestXhr.abort();
|
| - this.subtestXhr = null;
|
| - }
|
| - var bot = this.getCheckedBot();
|
| - // If no bot is selected, just leave the current subtests.
|
| - if (bot === null) {
|
| - return;
|
| - }
|
| - var suite = this.getCheckedSuite();
|
| - if (!suite) {
|
| - return;
|
| - }
|
| -
|
| - this.loading = true;
|
| -
|
| - var params = {
|
| - type: 'sub_tests',
|
| - suite: suite,
|
| - bots: bot,
|
| - xsrf_token: this.xsrfToken
|
| - };
|
| - this.subtestXhr = simple_xhr.send(
|
| - '/list_tests',
|
| - params,
|
| - function(response) {
|
| - this.loading = false;
|
| - this.subtestDict = response;
|
| - // Start at first subtest menu.
|
| - this.updateSubtestMenus(2);
|
| - }.bind(this),
|
| - function(error) {
|
| - // TODO: Display error.
|
| - this.loading = false;
|
| - }.bind(this)
|
| - );
|
| - },
|
| -
|
| - /**
|
| * Updates all subtest menus starting at 'startIndex'.
|
| */
|
| - updateSubtestMenus: function(startIndex) {
|
| - var subtestDict = this.getSubtestAtIndex(startIndex);
|
| -
|
| + updateSubtestMenus: async function(startIndex) {
|
| + let subtests = await this.subtests.getSubtestsForPath(
|
| + this.getCurrentSelectedPathUpTo(startIndex - 1));
|
| // Update existing subtest menu.
|
| for (var i = startIndex; i < this.selectionModels.length; i++) {
|
| - // Remove the rest of the menu if no subtestDict.
|
| - if (!subtestDict || Object.keys(subtestDict).length == 0) {
|
| + // Remove the rest of the menu if no subtests.
|
| + if (subtests === []) {
|
| this.splice('selectionModels', i);
|
| this.updateAddButtonState();
|
| return;
|
| }
|
| - var subtestItems = this.getSubtestItems(subtestDict);
|
| - var menu = this.getSelectionMenu(i);
|
| - menu.set('items', subtestItems);
|
| + const menu = this.getSelectionMenu(i);
|
| + menu.set('items', subtests);
|
|
|
| // If there are selected item, update next menu.
|
| if (menu.selectedItem) {
|
| - subtestDict = subtestDict[menu.selectedName]['sub_tests'];
|
| + subtests = await this.subtests.getSubtestsForPath(
|
| + this.getCurrentSelectedPathUpTo(i - 1, false));
|
| } else {
|
| - subtestDict = null;
|
| + subtests = [];
|
| }
|
| }
|
|
|
| - // Check if we still need to add a subtest menu.
|
| - if (subtestDict && Object.keys(subtestDict).length > 0) {
|
| - var subtestItems = this.getSubtestItems(subtestDict);
|
| + // If we reached the last iteration but still have subtests, that means
|
| + // that means that the last extant subtest selection still has subtests
|
| + // and we need to put those in a new menu.
|
| + if (subtests !== []) {
|
| this.push('selectionModels', {
|
| placeholder: this.SUBTEST_LABEL,
|
| - datalist: subtestItems,
|
| + datalist: subtests,
|
| disabled: false,
|
| });
|
| Polymer.dom.flush();
|
| - var menu = this.getSelectionMenu(this.selectionModels.length - 1);
|
| - menu.set('items', subtestItems);
|
| + const menu = this.getSelectionMenu(this.selectionModels.length - 1);
|
| + menu.set('items', subtests);
|
| }
|
|
|
| this.updateAddButtonState();
|
| @@ -387,32 +392,6 @@ found in the LICENSE file.
|
| this.enableAddSeries = this.getCurrentSelection() instanceof Array;
|
| },
|
|
|
| - getSubtestAtIndex: function(index) {
|
| - var subtestDict = this.subtestDict;
|
| - for (var i = 2; i < index; i++) {
|
| - var test = this.getSelectionMenu(i).selectedName;
|
| - if (test in subtestDict) {
|
| - subtestDict = subtestDict[test]['sub_tests'];
|
| - } else {
|
| - return null;
|
| - }
|
| - }
|
| - return subtestDict;
|
| - },
|
| -
|
| - getSubtestItems: function(subtestDict) {
|
| - var subtestItems = [];
|
| - var subtestNames = Object.keys(subtestDict).sort();
|
| - for (var i = 0; i < subtestNames.length; i++) {
|
| - var name = subtestNames[i];
|
| - subtestItems.push({
|
| - name: name,
|
| - tag: (subtestDict[name]['deprecated'] ? this.DEPRECATED_TAG : '')
|
| - });
|
| - }
|
| - return subtestItems;
|
| - },
|
| -
|
| getCheckedBot: function() {
|
| var botMenu = this.getSelectionMenu(1);
|
| if (botMenu.selectedItem) {
|
| @@ -458,14 +437,27 @@ found in the LICENSE file.
|
| * is a valid selection.
|
| */
|
| getCurrentSelection: function() {
|
| - var level = 0;
|
| - var parts = [];
|
| + const path = this.getCurrentSelectedPathUpTo(-1, true);
|
| +
|
| + if (this.currentSelectedPath_ === path) {
|
| + return this.currentSelectedTests_;
|
| + }
|
| + this.sendListTestsRequest(path);
|
| + return null;
|
| + },
|
| +
|
| + getCurrentSelectedPathUpTo: function(maxLevel, onlyValid) {
|
| + let level = 0;
|
| + const parts = [];
|
| while (true) {
|
| - var menu = this.getSelectionMenu(level);
|
| - if (!menu || !menu.selectedItem) {
|
| + if (maxLevel !== -1 && level <= maxLevel) {
|
| + break;
|
| + }
|
| + const menu = this.getSelectionMenu(level);
|
| + if (onlyValid && (!menu || !menu.selectedItem)) {
|
| // A selection is only valid if it specifies at least one subtest
|
| // component, which is the third level.
|
| - if (level <= 2) return null;
|
| + if (level <= 2) return undefined;
|
| break;
|
| } else {
|
| // We want to collect all the subtest components so we can form
|
| @@ -475,17 +467,12 @@ found in the LICENSE file.
|
| level += 1;
|
| }
|
|
|
| - var suite = this.getSelectionMenu(0).selectedItem.name;
|
| - var bot = this.getCheckedBot();
|
| + const suite = this.getSelectionMenu(0).selectedItem.name;
|
| + const bot = this.getCheckedBot();
|
| parts.unshift(suite);
|
| parts.unshift(bot);
|
|
|
| - var path = parts.join('/');
|
| -
|
| - if (this.currentSelectedPath_ === path)
|
| - return this.currentSelectedTests_;
|
| - this.sendListTestsRequest(path);
|
| - return null;
|
| + return parts.join('/');
|
| },
|
|
|
| getCurrentSelectedPath: function() {
|
|
|