Title: [196708] trunk/Websites/perf.webkit.org
Revision
196708
Author
rn...@webkit.org
Date
2016-02-17 12:18:05 -0800 (Wed, 17 Feb 2016)

Log Message

v3 UI has the capability to schedule an A/B testing in a specific range
https://bugs.webkit.org/show_bug.cgi?id=154329

Reviewed by Chris Dumez.

Extended AnalysisTaskChartPane and ResultsTable so that users can select a range of points in either
the overview chart pane and the results viewer table. Extracted TestGroupForm out of the analysis task
page and used right below those two components in the analysis task page.

* public/v3/components/results-table.js:
(ResultsTable):
(ResultsTable.prototype.setRangeSelectorLabels): Added.
(ResultsTable.prototype.setRangeSelectorCallback): Added.
(ResultsTable.prototype.selectedRange): Added.
(ResultsTable.prototype._rangeSelectorClicked): Added.
(ResultsTable.prototype.render): Generate radio boxes to select a range.

* public/v3/components/test-group-form.js:
(TestGroupForm):
(TestGroupForm.prototype.setStartCallback): Added.
(TestGroupForm.prototype.setNeedsName): Added.
(TestGroupForm.prototype.setDisabled): Added.
(TestGroupForm.prototype.setLabel): Added.
(TestGroupForm.prototype.setRepetitionCount): Added.
(TestGroupForm.prototype._submitted): Added.
(TestGroupForm.htmlTemplate): Extracted from AnalysisTaskPage.htmlTemplate.

* public/v3/index.html:

* public/v3/pages/analysis-task-page.js:
(AnalysisTaskChartPane.prototype._mainSelectionDidChange): Added. Delegates the work to AnalysisTaskPage.
(AnalysisTaskChartPane.prototype.selectedPoints): Added.
(AnalysisTaskPage):
(AnalysisTaskPage.prototype.title):
(AnalysisTaskPage.prototype.render):
(AnalysisTaskPage.prototype._renderTestGroupDetails): Use TestGroupForm's methods instead of mutating DOM. 
(AnalysisTaskPage.prototype._retryCurrentTestGroup):
(AnalysisTaskPage.prototype._chartSelectionDidChange): Added.
(AnalysisTaskPage.prototype._createNewTestGroupFromChart): Added.
(AnalysisTaskPage.prototype._selectedRowInAnalysisResultsViewer): Added.
(AnalysisTaskPage.prototype._createNewTestGroupFromViewer): Added.
(AnalysisTaskPage.prototype._createRetryNameForTestGroup):
(AnalysisTaskPage.prototype._createTestGroupAfterVerifyingRootSetList): Extracted from _retryCurrentTestGroup
so that we can call it in _createNewTestGroupFromChart and _createNewTestGroupFromViewer.
(AnalysisTaskPage.htmlTemplate):

Modified Paths

Added Paths

Diff

Modified: trunk/Websites/perf.webkit.org/ChangeLog (196707 => 196708)


--- trunk/Websites/perf.webkit.org/ChangeLog	2016-02-17 20:11:05 UTC (rev 196707)
+++ trunk/Websites/perf.webkit.org/ChangeLog	2016-02-17 20:18:05 UTC (rev 196708)
@@ -1,3 +1,51 @@
+2016-02-16  Ryosuke Niwa  <rn...@webkit.org>
+
+        v3 UI has the capability to schedule an A/B testing in a specific range
+        https://bugs.webkit.org/show_bug.cgi?id=154329
+
+        Reviewed by Chris Dumez.
+
+        Extended AnalysisTaskChartPane and ResultsTable so that users can select a range of points in either
+        the overview chart pane and the results viewer table. Extracted TestGroupForm out of the analysis task
+        page and used right below those two components in the analysis task page.
+
+        * public/v3/components/results-table.js:
+        (ResultsTable):
+        (ResultsTable.prototype.setRangeSelectorLabels): Added.
+        (ResultsTable.prototype.setRangeSelectorCallback): Added.
+        (ResultsTable.prototype.selectedRange): Added.
+        (ResultsTable.prototype._rangeSelectorClicked): Added.
+        (ResultsTable.prototype.render): Generate radio boxes to select a range.
+
+        * public/v3/components/test-group-form.js:
+        (TestGroupForm):
+        (TestGroupForm.prototype.setStartCallback): Added.
+        (TestGroupForm.prototype.setNeedsName): Added.
+        (TestGroupForm.prototype.setDisabled): Added.
+        (TestGroupForm.prototype.setLabel): Added.
+        (TestGroupForm.prototype.setRepetitionCount): Added.
+        (TestGroupForm.prototype._submitted): Added.
+        (TestGroupForm.htmlTemplate): Extracted from AnalysisTaskPage.htmlTemplate.
+
+        * public/v3/index.html:
+
+        * public/v3/pages/analysis-task-page.js:
+        (AnalysisTaskChartPane.prototype._mainSelectionDidChange): Added. Delegates the work to AnalysisTaskPage.
+        (AnalysisTaskChartPane.prototype.selectedPoints): Added.
+        (AnalysisTaskPage):
+        (AnalysisTaskPage.prototype.title):
+        (AnalysisTaskPage.prototype.render):
+        (AnalysisTaskPage.prototype._renderTestGroupDetails): Use TestGroupForm's methods instead of mutating DOM. 
+        (AnalysisTaskPage.prototype._retryCurrentTestGroup):
+        (AnalysisTaskPage.prototype._chartSelectionDidChange): Added.
+        (AnalysisTaskPage.prototype._createNewTestGroupFromChart): Added.
+        (AnalysisTaskPage.prototype._selectedRowInAnalysisResultsViewer): Added.
+        (AnalysisTaskPage.prototype._createNewTestGroupFromViewer): Added.
+        (AnalysisTaskPage.prototype._createRetryNameForTestGroup):
+        (AnalysisTaskPage.prototype._createTestGroupAfterVerifyingRootSetList): Extracted from _retryCurrentTestGroup
+        so that we can call it in _createNewTestGroupFromChart and _createNewTestGroupFromViewer.
+        (AnalysisTaskPage.htmlTemplate):
+
 2016-02-15  Ryosuke Niwa  <rn...@webkit.org>
 
         Extract the code specific to v2 UI out of shared statistics.js

Modified: trunk/Websites/perf.webkit.org/public/v3/components/results-table.js (196707 => 196708)


--- trunk/Websites/perf.webkit.org/public/v3/components/results-table.js	2016-02-17 20:11:05 UTC (rev 196707)
+++ trunk/Websites/perf.webkit.org/public/v3/components/results-table.js	2016-02-17 20:18:05 UTC (rev 196708)
@@ -4,10 +4,23 @@
         super(name);
         this._repositoryList = [];
         this._valueFormatter = null;
+        this._rangeSelectorLabels = null;
+        this._rangeSelectorCallback = null;
+        this._selectedRange = {};
     }
 
     setValueFormatter(valueFormatter) { this._valueFormatter = valueFormatter; }
+    setRangeSelectorLabels(labels) { this._rangeSelectorLabels = labels; }
+    setRangeSelectorCallback(callback) { this._rangeSelectorCallback = callback; }
+    selectedRange() { return this._selectedRange; }
 
+    _rangeSelectorClicked(label, row)
+    {
+        this._selectedRange[label] = row;
+        if (this._rangeSelectorCallback)
+            this._rangeSelectorCallback();
+    }
+
     render()
     {
         if (!this._valueFormatter)
@@ -23,13 +36,22 @@
         var barGraphGroup = new BarGraphGroup(this._valueFormatter);
         var element = ComponentBase.createElement;
         var self = this;
+        var hasGroupHeading = false;
         var tableBodies = rowGroups.map(function (group) {
             var groupHeading = group.heading;
             var revisionSupressionCount = {};
+            hasGroupHeading = !!groupHeading;
 
             return element('tbody', group.rows.map(function (row, rowIndex) {
                 var cells = [];
 
+                if (self._rangeSelectorLabels) {
+                    self._selectedRange = {};
+                    for (var label of self._rangeSelectorLabels)
+                        cells.push(element('td', element('input',
+                            {type: 'radio', name: label, onchange: self._rangeSelectorClicked.bind(self, label, row)})));
+                }
+
                 if (groupHeading !== undefined && !rowIndex)
                     cells.push(element('th', {rowspan: group.rows.length}, groupHeading));
                 cells.push(element('td', row.heading()));
@@ -47,6 +69,7 @@
 
         this.renderReplace(this.content().querySelector('table'), [
             element('thead', [
+                this._rangeSelectorLabels ? this._rangeSelectorLabels.map(function (label) { return element('th', label) }) : [],
                 this.heading(),
                 element('th', 'Result'),
                 repositoryList.map(function (repository) { return element('th', repository.label()); }),

Added: trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js (0 => 196708)


--- trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js	                        (rev 0)
+++ trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js	2016-02-17 20:18:05 UTC (rev 196708)
@@ -0,0 +1,55 @@
+
+class TestGroupForm extends ComponentBase {
+
+    constructor()
+    {
+        super('test-group-form');
+        this._startCallback = null;
+        this._repetitionCountControl = this.content().querySelector('.repetition-count');
+        this._repetitionCountControl.value = 4;
+        this._buttonControl = this.content().querySelector('button');
+        this._nameControl = this.content().querySelector('.name');
+        this.content().querySelector('form')._onsubmit_ = this._submitted.bind(this);
+    }
+
+    setStartCallback(callback) { this._startCallback = callback; }
+    setNeedsName(needsName) { this._nameControl.style.display = needsName ? null : 'none'; }
+    setDisabled(disabled) { this._buttonControl.disabled = disabled; }
+
+    setLabel(label) { this._buttonControl.textContent = label; }
+    setRepetitionCount(count) { this._repetitionCountControl.value = count; }
+
+    _submitted(event)
+    {
+        event.preventDefault();
+        if (this._startCallback)
+            this._startCallback(this._nameControl.value, this._repetitionCountControl.value);
+    }
+
+    static htmlTemplate()
+    {
+        return `
+            <form>
+                <button type="submit">Start A/B testing</button>
+                <input class="name" type="text">
+                with
+                <select class="repetition-count">
+                    <option>1</option>
+                    <option>2</option>
+                    <option>3</option>
+                    <option>4</option>
+                    <option>5</option>
+                    <option>6</option>
+                    <option>7</option>
+                    <option>8</option>
+                    <option>9</option>
+                    <option>10</option>
+                </select>
+                iterations per set
+            </form>
+        `;
+    }
+
+}
+
+ComponentBase.defineElement('test-group-form', TestGroupForm);

Modified: trunk/Websites/perf.webkit.org/public/v3/index.html (196707 => 196708)


--- trunk/Websites/perf.webkit.org/public/v3/index.html	2016-02-17 20:11:05 UTC (rev 196707)
+++ trunk/Websites/perf.webkit.org/public/v3/index.html	2016-02-17 20:18:05 UTC (rev 196708)
@@ -75,6 +75,7 @@
         <script src=""
         <script src=""
         <script src=""
+        <script src=""
         <script src=""
         <script src=""
         <script src=""

Modified: trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js (196707 => 196708)


--- trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js	2016-02-17 20:11:05 UTC (rev 196707)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js	2016-02-17 20:18:05 UTC (rev 196708)
@@ -8,6 +8,22 @@
 
     setPage(page) { this._page = page; }
     router() { return this._page.router(); }
+
+    _mainSelectionDidChange(selection, didEndDrag)
+    {
+        super._mainSelectionDidChange(selection);
+        if (didEndDrag)
+            this._page._chartSelectionDidChange();
+    }
+
+    selectedPoints()
+    {
+        var selection = this._mainChart ? this._mainChart.currentSelection() : null;
+        if (!selection)
+            return null;
+
+        return this._mainChart.sampledDataBetween('current', selection[0], selection[1]);
+    }
 }
 
 ComponentBase.defineElement('analysis-task-chart-pane', AnalysisTaskChartPane);
@@ -33,6 +49,8 @@
         this._chartPane.setPage(this);
         this._analysisResultsViewer = this.content().querySelector('analysis-results-viewer').component();
         this._analysisResultsViewer.setTestGroupCallback(this._showTestGroup.bind(this));
+        this._analysisResultsViewer.setRangeSelectorLabels(['A', 'B']);
+        this._analysisResultsViewer.setRangeSelectorCallback(this._selectedRowInAnalysisResultsViewer.bind(this));
         this._testGroupResultsTable = this.content().querySelector('test-group-results-table').component();
         this._taskNameLabel = this.content().querySelector('.analysis-task-name editable-text').component();
         this._taskNameLabel.setStartedEditingCallback(this._didStartEditingTaskName.bind(this));
@@ -45,7 +63,16 @@
         this._bugTrackerControl = this.content().querySelector('.bug-tracker-control');
         this._bugNumberControl = this.content().querySelector('.bug-number-control');
 
-        this.content().querySelector('.test-group-retry-form')._onsubmit_ = this._retryCurrentTestGroup.bind(this);
+        this._newTestGroupFormForChart = this.content().querySelector('.overview-chart test-group-form').component();
+        this._newTestGroupFormForChart.setStartCallback(this._createNewTestGroupFromChart.bind(this));
+
+        this._newTestGroupFormForViewer = this.content().querySelector('.analysis-results-view test-group-form').component();
+        this._newTestGroupFormForViewer.setStartCallback(this._createNewTestGroupFromViewer.bind(this));
+        this._selectedRowInAnalysisResultsViewer();
+
+        this._retryForm = this.content().querySelector('.test-group-retry-form').firstChild.component();
+        this._retryForm.setStartCallback(this._retryCurrentTestGroup.bind(this));
+        this._retryForm.setNeedsName(false);
     }
 
     title() { return this._task ? this._task.label() : 'Analysis Task'; }
@@ -228,6 +255,8 @@
                 }));
         }
 
+        this._newTestGroupFormForChart.render();
+
         this._analysisResultsViewer.setCurrentTestGroup(this._currentTestGroup);
         this._analysisResultsViewer.render();
 
@@ -297,16 +326,14 @@
                     this._chartPane.setMainSelection([startTime, endTime]);
             }
 
-            this.content().querySelector('.test-group-retry-button').textContent = this._currentTestGroup ? 'Retry' : 'Confirm the change';
+            this._retryForm.setLabel('Retry');
+            if (this._currentTestGroup)
+                this._retryForm.setRepetitionCount(this._currentTestGroup.repetitionCount());
+            this._retryForm.element().style.display = this._currentTestGroup ? null : 'none';
 
-            var repetitionCount = this._currentTestGroup ? this._currentTestGroup.repetitionCount() : 4;
-            var repetitionCountController = this.content().querySelector('.test-group-retry-repetition-count');
-            repetitionCountController.value = repetitionCount;
-
             this._renderedCurrentTestGroup = this._currentTestGroup;
         }
-
-        this.content().querySelector('.test-group-retry-button').disabled = !(this._currentTestGroup || this._startPoint);
+        this._retryForm.render();
     }
 
     _showTestGroup(testGroup)
@@ -390,26 +417,49 @@
         });
     }
 
-    _retryCurrentTestGroup(event)
+    _retryCurrentTestGroup(unusedName, repetitionCount)
     {
-        event.preventDefault();
-        console.assert(this._currentTestGroup || this._startPoint);
+        console.assert(this._currentTestGroup);
+        var testGroup = this._currentTestGroup;
+        var newName = this._createRetryNameForTestGroup(testGroup.name());
+        var rootSetList = testGroup.requestedRootSets();
+        var rootSetLabels = rootSetList.map(function (rootSet) { return testGroup.labelForRootSet(rootSet); });
+        return this._createTestGroupAfterVerifyingRootSetList(newName, repetitionCount, rootSetList, rootSetLabels);
+    }
 
-        var testGroupName;
-        var rootSetList;
-        var rootSetLabels;
+    _chartSelectionDidChange()
+    {
+        var points = this._chartPane.selectedPoints();
+        this._newTestGroupFormForChart.setDisabled(!points || points.length < 2);
+    }
 
-        if (this._currentTestGroup) {
-            var testGroup = this._currentTestGroup;
-            testGroupName = this._createRetryNameForTestGroup(testGroup.name());
-            rootSetList = testGroup.requestedRootSets();
-            rootSetLabels = rootSetList.map(function (rootSet) { return testGroup.labelForRootSet(rootSet); });
-        } else {
-            testGroupName = 'Confirming the change';
-            rootSetList = [this._startPoint.rootSet(), this._endPoint.rootSet()];
-            rootSetLabels = ['Point 0', `Point ${this._endPoint.seriesIndex - this._startPoint.seriesIndex}`];
-        }
+    _createNewTestGroupFromChart(name, repetitionCount)
+    {
+        var points = this._chartPane.selectedPoints();
+        console.assert(points && points.length >= 2);
+        return this._createTestGroupAfterVerifyingRootSetList(name, repetitionCount,
+            [points[0].rootSet(), points[points.length - 1].rootSet()], ['A', 'B']);
+    }
 
+    _selectedRowInAnalysisResultsViewer()
+    {
+        var selectedRange = this._analysisResultsViewer.selectedRange();
+        this._newTestGroupFormForViewer.setDisabled(!selectedRange['A'] || !selectedRange['B']);
+    }
+
+    _createNewTestGroupFromViewer(name, repetitionCount)
+    {
+        var selectedRange = this._analysisResultsViewer.selectedRange();
+        console.assert(selectedRange && selectedRange['A'] && selectedRange['B']);
+        return this._createTestGroupAfterVerifyingRootSetList(name, repetitionCount,
+            [selectedRange['A'].rootSet(), selectedRange['B'].rootSet()], ['A', 'B']);
+    }
+
+    _createTestGroupAfterVerifyingRootSetList(testGroupName, repetitionCount, rootSetList, rootSetLabels)
+    {
+        if (this._hasDuplicateTestGroupName(testGroupName))
+            alert(`There is already a test group named "${testGroupName}"`);
+
         var rootSetsByName = {};
         for (var repository of rootSetList[0].repositories())
             rootSetsByName[repository.name()] = [];
@@ -434,8 +484,6 @@
             }
         }
 
-        var repetitionCount = this.content().querySelector('.test-group-retry-repetition-count').value;
-
         TestGroup.createAndRefetchTestGroups(this._task, testGroupName, repetitionCount, rootSetsByName)
             .then(this._didFetchTestGroups.bind(this), function (error) {
             alert('Failed to create a new test group: ' + error);
@@ -507,31 +555,17 @@
                 </div>
                 <section class="overview-chart">
                     <analysis-task-chart-pane></analysis-task-chart-pane>
+                    <div class="new-test-group-form"><test-group-form></test-group-form></div>
                 </section>
                 <section class="analysis-results-view">
                     <analysis-results-viewer></analysis-results-viewer>
+                    <div class="new-test-group-form"><test-group-form></test-group-form></div>
                 </section>
                 <section class="test-group-view">
                     <ul class="test-group-list"></ul>
                     <div class="test-group-details">
                         <test-group-results-table></test-group-results-table>
-                        <form class="test-group-retry-form">
-                            <button class="test-group-retry-button" type="submit">Retry</button>
-                            with
-                            <select class="test-group-retry-repetition-count">
-                                <option>1</option>
-                                <option>2</option>
-                                <option>3</option>
-                                <option>4</option>
-                                <option>5</option>
-                                <option>6</option>
-                                <option>7</option>
-                                <option>8</option>
-                                <option>9</option>
-                                <option>10</option>
-                            </select>
-                            iterations per set
-                        </form>
+                        <div class="test-group-retry-form"><test-group-form></test-group-form></div>
                     </div>
                 </section>
             </div>
@@ -617,7 +651,7 @@
             }
 
             .analysis-results-view {
-                margin: 1rem;
+                margin: 2.5rem 1rem;
             }
 
             .test-configuration h3 {
@@ -641,6 +675,7 @@
                 margin: 0;
             }
 
+            .new-test-group-form,
             .test-group-retry-form {
                 padding: 0;
                 margin: 0.5rem;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to