Skip to content

Commit f5cef34

Browse files
authored
Add ui tests for beakerx and bqplot widgets (#10755)
* Add ui tests for beakerx and bqplot widgets * Bug fixes
1 parent 3e8761b commit f5cef34

6 files changed

Lines changed: 298 additions & 2 deletions

File tree

build/conda-functional-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ isort
1919
pathlib2>=2.2.0 ; python_version<'3.6' # Python 2.7 compatibility (pytest)
2020
pythreejs
2121
ipyvolume
22+
beakerx
23+
bqplot

src/client/datascience/jupyter/jupyterSession.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class JupyterSession implements IJupyterSession {
7878
this.statusHandler = this.onStatusChanged.bind(this);
7979
}
8080
private get jupyterLab(): undefined | typeof import('@jupyterlab/services') {
81-
if (this._jupyterLab) {
81+
if (!this._jupyterLab) {
8282
// tslint:disable-next-line:no-require-imports
8383
this._jupyterLab = require('@jupyterlab/services') as typeof import('@jupyterlab/services');
8484
}

src/client/datascience/jupyter/liveshare/guestJupyterNotebook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class GuestJupyterNotebook
3535
extends LiveShareParticipantGuest(LiveShareParticipantDefault, LiveShare.JupyterNotebookSharedService)
3636
implements INotebook, ILiveShareParticipant {
3737
private get jupyterLab(): undefined | typeof import('@jupyterlab/services') {
38-
if (this._jupyterLab) {
38+
if (!this._jupyterLab) {
3939
// tslint:disable-next-line:no-require-imports
4040
this._jupyterLab = require('@jupyterlab/services') as typeof import('@jupyterlab/services');
4141
}

src/test/datascience/uiTests/ipywidget.ui.functional.test.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ use(chaiAsPromised);
138138
async function openIPySheetsIpynb() {
139139
return openNotebookFile('ipySheet_widgets.ipynb');
140140
}
141+
async function openBeakerXIpynb() {
142+
return openNotebookFile('beakerx_widgets.ipynb');
143+
}
144+
async function openBqplotIpynb() {
145+
return openNotebookFile('bqplot_widgets.ipynb');
146+
}
141147
async function openIPyVolumeIpynb() {
142148
return openNotebookFile('ipyvolume_widgets.ipynb');
143149
}
@@ -237,6 +243,7 @@ use(chaiAsPromised);
237243
await retryIfFail(async () => {
238244
const cellOutput = await notebookUI.getCellOutputHTML(3);
239245

246+
// Confirm cells with output has been rendered.
240247
assert.include(cellOutput, 'Hello</td>');
241248
assert.include(cellOutput, 'World</td>');
242249
});
@@ -428,6 +435,99 @@ use(chaiAsPromised);
428435
assert.include(cellOutputHtml, '<canvas ');
429436
});
430437
});
438+
test('Render beakerx', async () => {
439+
const { notebookUI } = await openBeakerXIpynb();
440+
if (!ioc.mockJupyter) {
441+
await assert.eventually.isFalse(notebookUI.cellHasOutput(1));
442+
await assert.eventually.isFalse(notebookUI.cellHasOutput(2));
443+
await assert.eventually.isFalse(notebookUI.cellHasOutput(3));
444+
}
445+
446+
await notebookUI.executeCell(1);
447+
await retryIfFail(async () => {
448+
const cellOutputHtml = await notebookUI.getCellOutputHTML(1);
449+
// Confirm svg graph has been rendered.
450+
assert.include(cellOutputHtml, '<svg');
451+
452+
// Confirm graph legened has been rendered.
453+
const cellOutput = await notebookUI.getCellOutput(1);
454+
const legends = await cellOutput.$$('div.plot-legend');
455+
assert.isAtLeast(legends.length, 1);
456+
});
457+
458+
await notebookUI.executeCell(2);
459+
await retryIfFail(async () => {
460+
// Confirm graph modal dialog has been rendered.
461+
const cellOutput = await notebookUI.getCellOutput(2);
462+
const modals = await cellOutput.$$('div.modal-content');
463+
assert.isAtLeast(modals.length, 1);
464+
});
465+
466+
await notebookUI.executeCell(3);
467+
await retryIfFail(async () => {
468+
// Confirm form with fields have been rendered.
469+
const cellOutput = await notebookUI.getCellOutput(3);
470+
const textAreas = await cellOutput.$$('div.widget-textarea');
471+
assert.isAtLeast(textAreas.length, 1);
472+
});
473+
});
474+
test('Render bqplot', async () => {
475+
const { notebookUI } = await openBqplotIpynb();
476+
if (!ioc.mockJupyter) {
477+
await assert.eventually.isFalse(notebookUI.cellHasOutput(2));
478+
await assert.eventually.isFalse(notebookUI.cellHasOutput(4));
479+
}
480+
481+
await notebookUI.executeCell(1);
482+
await notebookUI.executeCell(2);
483+
484+
await retryIfFail(async () => {
485+
const cellOutputHtml = await notebookUI.getCellOutputHTML(2);
486+
// Confirm svg graph has been rendered.
487+
assert.include(cellOutputHtml, '<svg');
488+
assert.include(cellOutputHtml, 'plotarea_events');
489+
});
490+
491+
// Render empty plot
492+
await notebookUI.executeCell(4);
493+
await retryIfFail(async () => {
494+
const cellOutput = await notebookUI.getCellOutput(4);
495+
// Confirm no points have been rendered.
496+
const dots = await cellOutput.$$('path.dot');
497+
assert.equal(dots.length, 0);
498+
});
499+
500+
// Draw points on previous plot.
501+
await notebookUI.executeCell(5);
502+
await retryIfFail(async () => {
503+
const cellOutput = await notebookUI.getCellOutput(4);
504+
// Confirm points have been rendered.
505+
const dots = await cellOutput.$$('path.dot');
506+
assert.isAtLeast(dots.length, 1);
507+
});
508+
509+
// Chage color of plot points to red.
510+
await notebookUI.executeCell(7);
511+
await retryIfFail(async () => {
512+
const cellOutput = await notebookUI.getCellOutput(4);
513+
const dots = await cellOutput.$$('path.dot');
514+
assert.isAtLeast(dots.length, 1);
515+
const dotHtml = await notebookUI.page?.evaluate(ele => ele.outerHTML, dots[0]);
516+
// Confirm color of dot is red.
517+
assert.include(dotHtml || '', 'red');
518+
});
519+
520+
// Chage color of plot points to red.
521+
await notebookUI.executeCell(8);
522+
await retryIfFail(async () => {
523+
const cellOutput = await notebookUI.getCellOutput(4);
524+
const dots = await cellOutput.$$('path.dot');
525+
assert.isAtLeast(dots.length, 1);
526+
const dotHtml = await notebookUI.page?.evaluate(ele => ele.outerHTML, dots[0]);
527+
// Confirm color of dot is red.
528+
assert.include(dotHtml || '', 'yellow');
529+
});
530+
});
431531
});
432532
});
433533
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Prerequisites\n",
8+
"pip install beakerx"
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": 25,
14+
"metadata": {},
15+
"outputs": [],
16+
"source": [
17+
"from beakerx import *\n",
18+
"plot1 = Plot()\n",
19+
"plot1.add(Bars(displayName=\"Bar\", \n",
20+
" x=[20,40,60], \n",
21+
" y=[100, 120, 90], \n",
22+
" width=10))"
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": 26,
28+
"metadata": {},
29+
"outputs": [],
30+
"source": [
31+
"import random\n",
32+
"from beakerx import *\n",
33+
"dataH4 = []\n",
34+
"\n",
35+
"for x in range(1, 1100000):\n",
36+
" dataH4.append(random.gauss(0, 1))\n",
37+
"\n",
38+
"Histogram(data= dataH4, binCount= 10000)"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": 27,
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"from beakerx import *\n",
48+
"f5 = EasyForm(\"form5\")\n",
49+
"f5.addTextArea(\"field name\", value = \"5initial value5\")\n",
50+
"f5"
51+
]
52+
}
53+
],
54+
"metadata": {
55+
"language_info": {
56+
"codemirror_mode": {
57+
"name": "ipython",
58+
"version": 3
59+
},
60+
"file_extension": ".py",
61+
"mimetype": "text/x-python",
62+
"name": "python",
63+
"nbconvert_exporter": "python",
64+
"pygments_lexer": "ipython3",
65+
"version": "3.8.1-final"
66+
}
67+
},
68+
"nbformat": 4,
69+
"nbformat_minor": 1
70+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Prerequisites\n",
8+
"\n",
9+
"pip install bqplot"
10+
],
11+
"execution_count": null,
12+
"outputs": []
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": 126,
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"import numpy as np\n",
21+
"from bqplot import pyplot as plt\n",
22+
"\n",
23+
"# And creating some random data\n",
24+
"size = 100\n",
25+
"np.random.seed(0)\n",
26+
"x_data = np.arange(size)\n",
27+
"y_data = np.cumsum(np.random.randn(size) * 100.0)"
28+
]
29+
},
30+
{
31+
"cell_type": "code",
32+
"execution_count": 127,
33+
"metadata": {},
34+
"outputs": [],
35+
"source": [
36+
"plt.figure(title='My First Plot')\n",
37+
"plt.plot(x_data, y_data)\n",
38+
"plt.show()"
39+
]
40+
},
41+
{
42+
"cell_type": "markdown",
43+
"metadata": {},
44+
"source": [
45+
"## Using `bqplot`'s interactive elements"
46+
],
47+
"execution_count": null,
48+
"outputs": []
49+
},
50+
{
51+
"cell_type": "code",
52+
"execution_count": 128,
53+
"metadata": {},
54+
"outputs": [],
55+
"source": [
56+
"# Creating a new Figure and setting it's title\n",
57+
"plt.figure(title='My Second Chart')"
58+
]
59+
},
60+
{
61+
"cell_type": "code",
62+
"execution_count": 129,
63+
"metadata": {},
64+
"outputs": [],
65+
"source": [
66+
"# Let's assign the scatter plot to a variable\n",
67+
"scatter_plot = plt.scatter(x_data, y_data)\n",
68+
"scatter_plot.y = np.cumsum(np.random.randn(size) * 100.0)"
69+
]
70+
},
71+
{
72+
"cell_type": "markdown",
73+
"metadata": {},
74+
"source": [
75+
"# Change color of plots"
76+
],
77+
"execution_count": null,
78+
"outputs": []
79+
},
80+
{
81+
"cell_type": "code",
82+
"execution_count": null,
83+
"metadata": {},
84+
"outputs": [],
85+
"source": [
86+
"# Say, the color\n",
87+
"scatter_plot.colors = ['Red']"
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": null,
93+
"metadata": {},
94+
"outputs": [],
95+
"source": [
96+
"scatter_plot.colors = ['yellow']"
97+
]
98+
},
99+
{
100+
"cell_type": "code",
101+
"execution_count": null,
102+
"metadata": {},
103+
"outputs": [],
104+
"source": []
105+
}
106+
],
107+
"metadata": {
108+
"anaconda-cloud": {},
109+
"language_info": {
110+
"codemirror_mode": {
111+
"name": "ipython",
112+
"version": 3
113+
},
114+
"file_extension": ".py",
115+
"mimetype": "text/x-python",
116+
"name": "python",
117+
"nbconvert_exporter": "python",
118+
"pygments_lexer": "ipython3",
119+
"version": "3.8.1-final"
120+
}
121+
},
122+
"nbformat": 4,
123+
"nbformat_minor": 1
124+
}

0 commit comments

Comments
 (0)