Skip to content

Commit

Permalink
Added a new plan-level 'Run' button to the toolbar on the interactive…
Browse files Browse the repository at this point in the history
… UI (#981)
  • Loading branch information
rnemes authored Aug 24, 2023
1 parent af986e0 commit 7fa3d3f
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 14 deletions.
1 change: 1 addition & 0 deletions doc/newsfragments/2404_new.run_all_button.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Introduced a new plan-level Run button to the toolbar on the interactive GUI.
23 changes: 17 additions & 6 deletions testplan/runnable/interactive/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,24 +227,35 @@ def reset_test(self, test_uid, await_results=True):
self._update_reports([(self.test(test_uid).dry_run().report, [])])

def run_all_tests(
self, await_results: bool = True
self,
shallow_report: Optional[Dict] = None,
await_results: bool = True,
) -> Union[TestReport, Awaitable]:
"""
Runs all tests.
:param shallow_report: shallow report entry, optional
:param await_results: Whether to block until tests are finished,
defaults to True.
:return: If await_results is True, returns a testplan report.
Otherwise, returns a future which will yield a testplan report when
ready.
"""
if not await_results:
return self._run_async(self.run_all_tests)

self.logger.debug("Interactive mode: Run all tests")
return self._run_async(
self.run_all_tests, shallow_report=shallow_report
)

for test_uid in self.all_tests():
self.run_test(test_uid)
if shallow_report:
self.logger.debug("Interactive mode: Run filtered tests")
for multitest in shallow_report["entries"]:
self.run_test(
test_uid=multitest["name"], shallow_report=multitest
)
else:
self.logger.debug("Interactive mode: Run all tests")
for test_uid in self.all_tests():
self.run_test(test_uid=test_uid)

def run_test(
self,
Expand Down
15 changes: 13 additions & 2 deletions testplan/runnable/interactive/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,19 @@ def put(self):
new_runtime_status,
):
_check_execution_order(ihandler.report)
ihandler.report.runtime_status = RuntimeStatus.WAITING
ihandler.run_all_tests(await_results=False)
filtered = "entries" in shallow_report
if filtered:
entries = _extract_entries(shallow_report)
ihandler.report.set_runtime_status_filtered(
RuntimeStatus.WAITING,
entries,
)
else:
ihandler.report.runtime_status = RuntimeStatus.WAITING
ihandler.run_all_tests(
shallow_report=shallow_report if filtered else None,
await_results=False,
)

return _serialize_report_entry(ihandler.report)

Expand Down
43 changes: 40 additions & 3 deletions testplan/web_ui/testing/src/Report/InteractiveReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ReloadButton,
ResetButton,
AbortButton,
RunAllButton,
SaveButton,
} from "../Toolbar/InteractiveButtons";
import NavBreadcrumbs from "../Nav/NavBreadcrumbs";
Expand Down Expand Up @@ -63,6 +64,7 @@ class InteractiveReportComponent extends BaseReport {
this.resetAssertionStatus = this.resetAssertionStatus.bind(this);
this.resetReport = this.resetReport.bind(this);
this.abortTestplan = this.abortTestplan.bind(this);
this.runAll = this.runAll.bind(this);
this.reloadCode = this.reloadCode.bind(this);
this.envCtrlCallback = this.envCtrlCallback.bind(this);
this.handleClick = this.handleClick.bind(this);
Expand All @@ -72,6 +74,7 @@ class InteractiveReportComponent extends BaseReport {
navWidth: `${INTERACTIVE_COL_WIDTH}em`,
resetting: false,
reloading: false,
running: false,
aborting: false,
assertionStatus: defaultAssertionStatus,
};
Expand Down Expand Up @@ -122,9 +125,12 @@ class InteractiveReportComponent extends BaseReport {
response.data.runtime_status === "finished" ||
response.data.runtime_status === "not_run"
) {
if (this.state.resetting){
if (this.state.resetting) {
this.setState({ resetting: false });
}
if (this.state.running) {
this.setState({ running: false });
}
}
if (
!this.state.report ||
Expand Down Expand Up @@ -503,11 +509,33 @@ class InteractiveReportComponent extends BaseReport {
return shallowEntry;
}

/**
* Send request of start all tests to server.
*/
runAll() {
if (
this.state.resetting || this.state.reloading ||
this.state.aborting || this.state.running
) {
return;
} else {
const updatedReportEntry = {
...this.shallowReportEntry(this.state.filteredReport.report),
runtime_status: "running",
};
this.putUpdatedReportEntry(updatedReportEntry);
this.setState({ running: true });
}
}

/**
* Reset the report state to "resetting" and request the change to server.
*/
resetReport() {
if (this.state.resetting || this.state.reloading || this.state.aborting) {
if (
this.state.resetting || this.state.reloading ||
this.state.aborting || this.state.running
) {
return;
} else {
const updatedReportEntry = {
Expand All @@ -523,7 +551,10 @@ class InteractiveReportComponent extends BaseReport {
* Send request of reloading report to server.
*/
reloadCode() {
if (this.state.resetting || this.state.reloading || this.state.aborting) {
if (
this.state.resetting || this.state.reloading ||
this.state.aborting || this.state.running
) {
return;
}
let currentTime = new Date();
Expand Down Expand Up @@ -670,6 +701,12 @@ class InteractiveReportComponent extends BaseReport {
updateEmptyDisplayFunc={noop}
updateTagsDisplayFunc={noop}
extraButtons={[
<RunAllButton
key="runall-button"
running={this.state.running}
runAllCbk={this.runAll}
filter={this.state.filteredReport.filter.text}
/>,
<ReloadButton
key="reload-button"
reloading={this.state.reloading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -683,4 +683,93 @@ describe("InteractiveReport", () => {
});
});
});

it("Run all tests", (done) => {
const interactiveReport = renderInteractiveReport();

const report = initialReport();
const multitest = report.entries[0];
expect(multitest.category).toBe("multitest");
multitest.env_status = "STARTED";

const testcase = report.entries[0].entries[0].entries[0];
expect(testcase.category).toBe("testcase");

interactiveReport.setState({
filteredReport: {
report: report,
filter: {text: null}
},
});
interactiveReport.update();
interactiveReport.instance().runAll();
moxios.wait(() => {
const request = moxios.requests.mostRecent();
expect(request.url).toBe("/api/v1/interactive/report");
expect(request.config.method).toBe("put");
const putData = JSON.parse(request.config.data);

request
.respondWith({
status: 200,
response: putData,
})
.then(() => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
expect(request.url).toBe("/api/v1/interactive/report");
expect(request.config.method).toBe("put");
const putData = JSON.parse(request.config.data);
expect(putData.runtime_status).toBe("running");
expect(putData.entries).not.toBeDefined();
done();
});
});
});
});

it("Run filtered tests", (done) => {
const interactiveReport = renderInteractiveReport();

const report = initialReport();
const multitest = report.entries[0];
expect(multitest.category).toBe("multitest");
multitest.env_status = "STARTED";

const testcase = report.entries[0].entries[0].entries[0];
expect(testcase.category).toBe("testcase");

interactiveReport.setState({
filteredReport: {
report: report,
filter: {text: "something"}
},
});
interactiveReport.update();
interactiveReport.instance().runAll();
moxios.wait(() => {
const request = moxios.requests.mostRecent();
expect(request.url).toBe("/api/v1/interactive/report");
expect(request.config.method).toBe("put");
const putData = JSON.parse(request.config.data);

request
.respondWith({
status: 200,
response: putData,
})
.then(() => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
expect(request.url).toBe("/api/v1/interactive/report");
expect(request.config.method).toBe("put");
const putData = JSON.parse(request.config.data);
expect(putData.runtime_status).toBe("running");
expect(putData.entries).toHaveLength(1);
expect(putData.entries[0].name).toBe("MultiTestName");
done();
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ exports[`InteractiveReport Handles environment being started 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -92,6 +97,11 @@ exports[`InteractiveReport Parially refreshes the report on update. 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -174,6 +184,11 @@ exports[`InteractiveReport Updates testcase state 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -653,6 +668,11 @@ exports[`InteractiveReport handles individual parametrizations being run 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -735,6 +755,11 @@ exports[`InteractiveReport handles individual test suites being run 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -817,6 +842,11 @@ exports[`InteractiveReport handles individual testcases being run 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down Expand Up @@ -899,6 +929,11 @@ exports[`InteractiveReport handles tests being run 1`] = `
expandStatus="default"
extraButtons={
Array [
<RunAllButton
filter={null}
runAllCbk={[Function]}
running={false}
/>,
<ReloadButton
reloadCbk={[Function]}
reloading={false}
Expand Down
Loading

0 comments on commit 7fa3d3f

Please sign in to comment.