diff --git a/tests/widget_lib/widget_lib/__init__.py b/tests/widget_lib/widget_lib/__init__.py index 333a2d419..e0bd3971d 100644 --- a/tests/widget_lib/widget_lib/__init__.py +++ b/tests/widget_lib/widget_lib/__init__.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright (c) Trung Le. # Distributed under the terms of the Modified BSD License. -from .example import ModuleImportError, ViewRenderError, ModelInitializationError +from .example import ModuleImportError, ViewRenderError, ModelInitializationError, WrongVersion from ._version import __version__, version_info # noqa -__all__ = ['ModuleImportError', 'ViewRenderError', 'ModelInitializationError'] +__all__ = ['ModuleImportError', 'ViewRenderError', + 'ModelInitializationError', 'WrongVersion'] def _jupyter_labextension_paths(): diff --git a/tests/widget_lib/widget_lib/example.py b/tests/widget_lib/widget_lib/example.py index 5bfb4bf9c..0af23b9ff 100644 --- a/tests/widget_lib/widget_lib/example.py +++ b/tests/widget_lib/widget_lib/example.py @@ -8,7 +8,7 @@ TODO: Add module docstring """ -from ipywidgets import DOMWidget +from ipywidgets import DOMWidget, Button from traitlets import Unicode from ._frontend import module_name, module_version @@ -42,3 +42,7 @@ class ModuleImportError(DOMWidget): _view_name = Unicode('ModuleImportErrorView').tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) + + +class WrongVersion(Button): + _model_module_version = Unicode('0.0').tag(sync=True) \ No newline at end of file diff --git a/ui-tests/notebooks/missing_module_inside_box.ipynb b/ui-tests/notebooks/missing_module_inside_box.ipynb new file mode 100644 index 000000000..b5e87ddee --- /dev/null +++ b/ui-tests/notebooks/missing_module_inside_box.ipynb @@ -0,0 +1,54 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "6e2208b3-955c-4842-84f0-fe70bf40b0e0", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "from widget_lib import ModuleImportError" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea0d27ef-8a31-4191-ad09-33e4194db736", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.HBox([ModuleImportError(), widgets.Button(description='ModuleImportError')])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fadff0a0-f4e6-46a4-8272-0ca10f1b077f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ui-tests/notebooks/module_error_inside_box.ipynb b/ui-tests/notebooks/module_error_inside_box.ipynb new file mode 100644 index 000000000..e390f0d82 --- /dev/null +++ b/ui-tests/notebooks/module_error_inside_box.ipynb @@ -0,0 +1,46 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "6e2208b3-955c-4842-84f0-fe70bf40b0e0", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "from widget_lib import ModelInitializationError" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "338bbb1f-e4c8-4fa7-98e6-d5ddfa97747c", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.HBox([ModelInitializationError(), widgets.Button(description='ModelInitializationError')])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ui-tests/notebooks/render_error_inside_box.ipynb b/ui-tests/notebooks/render_error_inside_box.ipynb new file mode 100644 index 000000000..9327b6c75 --- /dev/null +++ b/ui-tests/notebooks/render_error_inside_box.ipynb @@ -0,0 +1,46 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "6e2208b3-955c-4842-84f0-fe70bf40b0e0", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "from widget_lib import ViewRenderError" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce2fe832-1c7f-4a08-a247-353e90ac5b83", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.HBox([ViewRenderError(), widgets.Button(description='ViewRenderError')])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ui-tests/notebooks/wrong_semver.ipynb b/ui-tests/notebooks/wrong_semver.ipynb new file mode 100644 index 000000000..f4e5b01eb --- /dev/null +++ b/ui-tests/notebooks/wrong_semver.ipynb @@ -0,0 +1,66 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "7c6c297e-f753-47cd-9444-0aea73d17cb4", + "metadata": {}, + "outputs": [], + "source": [ + "from widget_lib import WrongVersion\n", + "import ipywidgets as widgets" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a03447e8-7c38-432d-985c-f89d6e87da60", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.Button(description = 'First button')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dea42641-00d5-4420-9f6f-131110c8e4c8", + "metadata": {}, + "outputs": [], + "source": [ + "WrongVersion()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "207cf497-d839-414a-bb4d-94727637268c", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.Button(description = 'Second button')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ui-tests/notebooks/wrong_semver_inside_box.ipynb b/ui-tests/notebooks/wrong_semver_inside_box.ipynb new file mode 100644 index 000000000..682b7eb42 --- /dev/null +++ b/ui-tests/notebooks/wrong_semver_inside_box.ipynb @@ -0,0 +1,46 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "6e2208b3-955c-4842-84f0-fe70bf40b0e0", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "from widget_lib import WrongVersion" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6abe59b-70b1-4f4f-9aa4-7fd04c87a01b", + "metadata": {}, + "outputs": [], + "source": [ + "widgets.HBox([WrongVersion(), widgets.Button(description='WrongVersion')])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ui-tests/stability_test/stability.test.ts b/ui-tests/stability_test/stability.test.ts index 14d7007c3..eddb0cdb0 100644 --- a/ui-tests/stability_test/stability.test.ts +++ b/ui-tests/stability_test/stability.test.ts @@ -31,6 +31,20 @@ test.describe('Voila stability Tests', () => { ); expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); }); + test('Should render notebook with missing module in a box', async ({ + page, + browserName + }, testInfo) => { + const notebookName = 'missing_module_inside_box'; + await page.goto(`render/${notebookName}.ipynb`); + await page.waitForSelector('button'); + await page.$('text=Typesetting math: 100%'); + await page.waitForSelector('#MathJax_Message', { state: 'hidden' }); + expect(errorLogs).toContain( + 'Class ModuleImportErrorModel not found in module widget_lib@^0.1.0' + ); + expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); + }); test('Should render notebook with model error', async ({ page, @@ -57,4 +71,19 @@ test.describe('Voila stability Tests', () => { expect(errorLogs).toContain('Error: Could not create view'); expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); }); + + test('Should render notebook with semver error', async ({ + page, + browserName + }, testInfo) => { + const notebookName = 'wrong_semver'; + await page.goto(`render/${notebookName}.ipynb`); + await page.waitForSelector('button'); + await page.$('text=Typesetting math: 100%'); + await page.waitForSelector('#MathJax_Message', { state: 'hidden' }); + expect(errorLogs).toContain( + 'Error: Module @jupyter-widgets/controls, semver range 0.0 is not registered as a widget module' + ); + expect(await page.screenshot()).toMatchSnapshot(`${notebookName}.png`); + }); }); diff --git a/ui-tests/stability_test/stability.test.ts-snapshots/wrong-semver-stability-test-linux.png b/ui-tests/stability_test/stability.test.ts-snapshots/wrong-semver-stability-test-linux.png new file mode 100644 index 000000000..14c99fc62 Binary files /dev/null and b/ui-tests/stability_test/stability.test.ts-snapshots/wrong-semver-stability-test-linux.png differ