Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QA] e2e screenshots tests #1025

Merged
merged 54 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
558adb8
test screenshots setup
l0uden Feb 18, 2025
1cca8af
test screenshots setup
l0uden Feb 18, 2025
022cc2c
test screenshots setup
l0uden Feb 18, 2025
3a3ac60
test screenshots setup
l0uden Feb 18, 2025
0d9f775
test screenshots setup
l0uden Feb 18, 2025
c69d1a3
test screenshots setup
l0uden Feb 18, 2025
afd0fb8
test screenshots setup
l0uden Feb 18, 2025
359adee
test screenshots setup
l0uden Feb 18, 2025
6d1745b
test screenshots setup
l0uden Feb 18, 2025
0237760
test screenshots setup
l0uden Feb 19, 2025
b682055
test screenshots setup
l0uden Feb 19, 2025
9b3cc35
mobile screenshots
l0uden Feb 19, 2025
b939e25
Merge branch 'main' of https://github.com/mckinsey/vizro into qa/e2e_…
l0uden Feb 19, 2025
cf40835
path to custom components
l0uden Feb 19, 2025
fd375d9
fix pythonpath
l0uden Feb 19, 2025
390119f
test run fixed
l0uden Feb 19, 2025
1defed0
callback waiter
l0uden Feb 20, 2025
bd22b0b
new screenshots
l0uden Feb 20, 2025
703b198
callback waiter before
l0uden Feb 20, 2025
1e75a72
callback waiter as a fixture
l0uden Feb 20, 2025
1b7e3b1
navbar dashboards
l0uden Feb 20, 2025
b9c0465
update screenshots
l0uden Feb 20, 2025
1a65a7e
navbar dashboard changes
l0uden Feb 20, 2025
086e15d
navbar dashboard changes
l0uden Feb 20, 2025
9c2fc90
new threashold
l0uden Feb 20, 2025
caa16ae
dynamic data test
l0uden Feb 21, 2025
45ee778
dynamic data test
l0uden Feb 21, 2025
227e089
new screenshots
l0uden Feb 21, 2025
d03f506
new slider click for firefox
l0uden Feb 21, 2025
6298c10
new slider click for firefox
l0uden Feb 21, 2025
6fcf3e8
update screenshot
l0uden Feb 21, 2025
43ce57c
update screenshot
l0uden Feb 21, 2025
63d4041
update screenshot
l0uden Feb 21, 2025
3731c82
Merge branch 'main' of https://github.com/mckinsey/vizro into qa/e2e_…
l0uden Feb 24, 2025
780140e
threshold = 0
l0uden Feb 24, 2025
8edec9f
new screenshots
l0uden Feb 24, 2025
dbd501e
threshold = 0.11
l0uden Feb 24, 2025
1456d01
threshold = 0.11
l0uden Feb 24, 2025
26f5ffd
check different title allignment
l0uden Feb 25, 2025
f9f0ed0
check incorrect navbar background
l0uden Feb 25, 2025
85e1e66
revert changes
l0uden Feb 25, 2025
ad9081e
Merge branch 'main' of https://github.com/mckinsey/vizro into qa/e2e_…
l0uden Feb 25, 2025
e447144
review fixes
l0uden Feb 27, 2025
49be31a
review fixes
l0uden Feb 27, 2025
b1429a5
Merge branch 'main' of https://github.com/mckinsey/vizro into qa/e2e_…
l0uden Feb 27, 2025
dd5ce68
tiny review fixes
l0uden Feb 28, 2025
112c40a
delete ff setup
l0uden Feb 28, 2025
c066df3
review fixes
l0uden Mar 3, 2025
02f2fdd
update screenshots
l0uden Mar 3, 2025
583c147
review fixes
l0uden Mar 3, 2025
f275728
review fixes
l0uden Mar 3, 2025
bb9b560
moved dynamic data test to dom elements tests
l0uden Mar 3, 2025
2d2a7ab
add pixelmatch to dom elements tests
l0uden Mar 3, 2025
802ad88
for tests rerun
l0uden Mar 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ runs:
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: Failed screenshots
name: Failed screenshots ${{ env.FAILED_SCREENSHOTS_ARCHIVE_POSTFIX }}
path: |
${{ env.PROJECT_PATH }}failed_screenshots

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test-e2e-component-library-vizro-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:
- name: Install Hatch
run: pip install hatch

- name: Install pixelmatch
run: sudo npm install pixelmatch -g

- name: Show dependency tree
run: hatch run pip tree

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/test-e2e-vizro-dom-elements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ env.PYTHON_VERSION }}
- name: Set up Python ${{ matrix.config.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
python-version: ${{ matrix.config.python-version }}

- name: Install Hatch
run: pip install hatch

- name: Install pixelmatch
run: sudo npm install pixelmatch -g

- name: Show dependency tree
run: hatch run pip tree

Expand Down
64 changes: 64 additions & 0 deletions .github/workflows/test-e2e-vizro-screenshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: e2e vizro screenshots tests

defaults:
run:
working-directory: vizro-core

on:
push:
branches: [main]
pull_request:
branches:
- main

env:
PYTHONUNBUFFERED: 1
FORCE_COLOR: 1
PYTHON_VERSION: "3.12"

jobs:
test-e2e-vizro-screenshots:
name: test-e2e-vizro-screenshots for ${{ matrix.config.browser }}
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
config:
- browser: chrome
command: "-m 'not mobile_screenshots'"
- browser: chrome_mobile
command: "-m mobile_screenshots"
- browser: firefox
command: "--webdriver Firefox -m 'not mobile_screenshots'"

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install Hatch
run: pip install hatch

- name: Install pixelmatch
run: sudo npm install pixelmatch -g

- name: Show dependency tree
run: hatch run pip tree

- name: Run e2e vizro-screenshots tests
run: |
export BROWSER=${{ matrix.config.browser }}
hatch run test-e2e-vizro-screenshots ${{ matrix.config.command }}

- name: Create artifacts and slack notifications
if: failure()
uses: ./.github/actions/failed-artifacts-and-slack-notifications
env:
TESTS_NAME: Vizro e2e vizro screenshots tests for ${{ matrix.config.browser }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
PROJECT_PATH: /home/runner/work/vizro/vizro/vizro-core/
FAILED_SCREENSHOTS_ARCHIVE_POSTFIX: ${{ matrix.config.browser }}
22 changes: 17 additions & 5 deletions vizro-core/hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@ dependencies = [
"jupyter",
"pre-commit",
"PyGithub",
"imutils",
"opencv-python",
"pyhamcrest",
"gunicorn"
"gunicorn",
"pixelmatch"
]
features = ["kedro"]
installer = "uv"

[envs.default.env-vars]
PYTHONPATH = "tests/e2e/vizro/dashboards/default:tests/tests_utils"
PYTHONPATH = "tests/e2e/vizro/dashboards/default:tests/tests_utils:tests/e2e/vizro/custom_components"

[envs.default.scripts]
download-static-files = "python tools/download_static_files.py"
Expand Down Expand Up @@ -63,12 +62,25 @@ templates-check = ["python src/vizro/_themes/generate_plotly_templates.py --chec
# fix this, but we don't actually use `hatch run test` anywhere right now.
# See comments added in https://github.com/mckinsey/vizro/pull/444.
test = "pytest tests --headless {args}"
test-e2e-component-library = "pytest tests/e2e/component_library/test_component_library.py --headless {args}"
test-e2e-component-library = "pytest -vs tests/e2e/component_library/test_component_library.py --headless {args}"
test-e2e-vizro-dom-elements = [
"gunicorn dashboard:app -b 0.0.0.0:5002 -w 1 --timeout 90 &",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5002 -t 30",
"pytest -vs --reruns 1 tests/e2e/vizro/test_dom_elements --headless {args}"
]
test-e2e-vizro-screenshots = [
"gunicorn dashboard:app -b 0.0.0.0:5002 -w 1 --timeout 90 &",
"gunicorn dashboard_one_page:app -b 0.0.0.0:5003 -w 1 --timeout 90 &",
"gunicorn dashboard_navbar_accordions:app -b 0.0.0.0:5004 -w 1 --timeout 90 &",
"gunicorn dashboard_navbar_pages:app -b 0.0.0.0:5005 -w 1 --timeout 90 &",
"gunicorn dashboard_navbar_navlink:app -b 0.0.0.0:5006 -w 1 --timeout 90 &",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5002 -t 30",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5003 -t 30",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5004 -t 30",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5005 -t 30",
"tests/tests_utils/e2e/vizro/dashboards/wait-for-it.sh 127.0.0.1:5006 -t 30",
"pytest -vs --reruns 1 tests/e2e/vizro/test_screenshots/ --headless {args}"
]
test-integration = "pytest tests/integration --headless {args}"
test-js = "./tools/run_jest.sh {args}"
test-unit = "pytest tests/unit {args}"
Expand Down
7 changes: 6 additions & 1 deletion vizro-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ filterwarnings = [
"ignore:HTTPResponse.getheader():DeprecationWarning",
# Ignore deprecation warning as it comes from the plotly default template. In our templates `vizro_dark` and
# `vizro_light`, we do not use mapbox anymore, see: https://github.com/mckinsey/vizro/pull/974
"ignore:.*scattermapbox.*is deprecated.*Use.*scattermap.*instead:DeprecationWarning"
"ignore:.*scattermapbox.*is deprecated.*Use.*scattermap.*instead:DeprecationWarning",
# ignore this warning for firefox screenshot tests
"ignore:get_logs always return None with webdrivers other than Chrome"
]
markers = [
"mobile_screenshots: marks tests for chrome mobile screenshots"
]
norecursedirs = ["tests/tests_utils", "tests/js"]
pythonpath = ["tests/tests_utils"]
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,35 +1,57 @@
import os

import e2e.vizro.constants as cnst
import pytest
from e2e.vizro.checkers import browser_console_warnings_checker
from e2e.vizro.waiters import callbacks_finish_waiter
from selenium.common import WebDriverException
from selenium.webdriver.chrome.options import Options as ChromeOptions


# dash_br_driver options hook
def pytest_setup_options():
options = ChromeOptions()
options.add_argument("--headless")
options.add_argument("--window-size=1920,1080")
return options
if os.getenv("BROWSER") == "chrome_mobile":
options = ChromeOptions()
options.add_experimental_option("mobileEmulation", {"deviceName": "iPhone 14 Pro Max"})
return options


def make_teardown(dash_br):
# TODO: move it after the specific test execution (after moving test to vizro repo)
# rewriting dynamic_filters_data.yml after each test
# data = {
# "max": 7,
# "min": 6,
# "setosa": 5,
# "versicolor": 10,
# "virginica": 15,
# }
# with open(cnst.DYNAMIC_FILTERS_DATA_CONFIG, "w") as file:
# yaml.dump(data, file)

# checking for browser console errors
try:
log_levels = [level for level in dash_br.get_logs() if level["level"] == "SEVERE" or "WARNING"]
if log_levels:
for log_level in log_levels:
browser_console_warnings_checker(log_level, log_levels)
except WebDriverException:
pass
if os.getenv("BROWSER") in ["chrome", "chrome_mobile"]:
try:
error_logs = [log for log in dash_br.get_logs() if log["level"] == "SEVERE" or "WARNING"]
for log in error_logs:
browser_console_warnings_checker(log, error_logs)
except WebDriverException:
pass


@pytest.fixture(autouse=True)
def dash_br_driver(dash_br, request):
"""Built-in driver from the dash library."""
port = request.param.get("port", cnst.DEFAULT_PORT) if hasattr(request, "param") else cnst.DEFAULT_PORT
path = request.param.get("path", "") if hasattr(request, "param") else ""
dash_br.driver.set_window_size(1920, 1080)
dash_br.server_url = f"http://127.0.0.1:{port}/{path}"
return dash_br


@pytest.fixture(autouse=True)
def wait_for_callbacks(dash_br):
callbacks_finish_waiter(dash_br)


@pytest.fixture(autouse=True)
Expand Down
3 changes: 3 additions & 0 deletions vizro-core/tests/e2e/vizro/dashboards/assets/banner.svg
24 changes: 24 additions & 0 deletions vizro-core/tests/e2e/vizro/dashboards/assets/css/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.anchor-container {
align-items: center;
background: var(--text-primary);
border-top-left-radius: 8px;
bottom: 0;
color: var(--text-primary-inverted) !important;
display: flex;
font-size: 0.8rem;
font-weight: 500;
height: 24px;
padding: 0 12px;
position: fixed;
right: 0;
}

.anchor-container:focus,
.anchor-container:hover {
background: var(--text-secondary);
color: var(--text-primary-inverted);
}

img#banner {
height: 16px;
}
28 changes: 26 additions & 2 deletions vizro-core/tests/e2e/vizro/dashboards/default/dashboard.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
import e2e.vizro.constants as cnst
from pages.ag_grid_page import ag_grid_page
from pages.datepicker_page import datepicker_page
from pages.dynamic_data_page import dynamic_data_page
from pages.dynamic_filters_pages import dynamic_filters_categorical_page, dynamic_filters_numerical_page
from pages.filter_interactions_page import filter_interactions_page
from pages.filters_page import filters_page
from pages.homepage import homepage
from pages.kpi_indicators_page import kpi_indicators_page
from pages.parameters_page import parameters_page
from pages.table_interactions_page import table_interactions_page
from pages.table_page import table_page

import vizro.models as vm
from vizro import Vizro

dashboard = vm.Dashboard(
title="Vizro dashboard for integration testing",
pages=[homepage, filters_page, parameters_page, kpi_indicators_page, datepicker_page, ag_grid_page],
pages=[
homepage,
filters_page,
parameters_page,
filter_interactions_page,
kpi_indicators_page,
datepicker_page,
ag_grid_page,
table_page,
table_interactions_page,
dynamic_data_page,
dynamic_filters_categorical_page,
dynamic_filters_numerical_page,
],
navigation=vm.Navigation(
pages={
cnst.GENERAL_ACCORDION: [
cnst.HOME_PAGE_ID,
cnst.FILTERS_PAGE,
cnst.PARAMETERS_PAGE,
cnst.FILTER_INTERACTIONS_PAGE,
cnst.KPI_INDICATORS_PAGE,
],
cnst.DATEPICKER_ACCORDION: [cnst.DATEPICKER_PAGE],
cnst.AG_GRID_ACCORDION: [cnst.TABLE_AG_GRID_PAGE],
cnst.AG_GRID_ACCORDION: [cnst.TABLE_PAGE, cnst.TABLE_INTERACTIONS_PAGE, cnst.TABLE_AG_GRID_PAGE],
cnst.DYNAMIC_DATA_ACCORDION: [
cnst.DYNAMIC_DATA_PAGE,
cnst.DYNAMIC_FILTERS_NUMERICAL_PAGE,
cnst.DYNAMIC_FILTERS_CATEGORICAL_PAGE,
],
}
),
theme="vizro_light",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import dash_bootstrap_components as dbc
import e2e.vizro.constants as cnst
from dash import get_asset_url, html
from pages.homepage import homepage
from pages.kpi_indicators_page import kpi_indicators_page

import vizro.models as vm
from vizro import Vizro

dashboard = vm.Dashboard(
title="Vizro dashboard for integration testing",
pages=[
homepage,
kpi_indicators_page,
],
navigation=vm.Navigation(
pages={
cnst.GENERAL_ACCORDION: [cnst.HOME_PAGE_ID],
cnst.KPI_ACCORDION: [cnst.KPI_INDICATORS_PAGE],
},
nav_selector=vm.NavBar(),
),
)

app = Vizro(assets_folder="../assets").build(dashboard)
app.dash.layout.children.append(
dbc.NavLink(
[
"Made with ",
html.Img(src=get_asset_url("banner.svg"), id="banner", alt="Vizro logo"),
"vizro",
],
href="https://github.com/mckinsey/vizro",
target="_blank",
className="anchor-container",
)
)

if __name__ == "__main__":
app.run(debug=True)
Loading