From 00a63811be0aac6e5159e6a52648b07d41a3adda Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Tue, 9 Mar 2021 07:51:09 +0000 Subject: [PATCH] chore: Simplify tests --- .github/workflows/ci.yml | 42 ++++----------- buildbots/assets/stub.py | 9 ---- .../assets/test-reference-count-async.py | 45 ---------------- buildbots/test-package-installations.sh | 30 ----------- buildbots/test-reference-count.sh | 25 --------- setup.cfg | 1 + tests/assets/client.py | 33 ++++++++++++ tests/test_generation_scripts.py | 32 ++++++++---- tests/test_installation.py | 52 +++++++++++++++++++ tests/test_reference_count_async.py | 52 +++++++++++++++++++ 10 files changed, 170 insertions(+), 151 deletions(-) delete mode 100644 buildbots/assets/stub.py delete mode 100644 buildbots/assets/test-reference-count-async.py delete mode 100644 buildbots/test-package-installations.sh delete mode 100644 buildbots/test-reference-count.sh create mode 100644 tests/assets/client.py create mode 100644 tests/test_installation.py create mode 100644 tests/test_reference_count_async.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59dc782e6..42558e47a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,6 @@ jobs: git diff exit 1 fi - - name: Run reference checks - run: bash buildbots/test-reference-count.sh build: name: Build timeout-minutes: 30 @@ -87,19 +85,25 @@ jobs: - name: Install browsers run: python -m playwright install - name: Common Tests - run: pytest -vv tests/common --browser=${{ matrix.browser }} --timeout 90 + run: pytest tests/common --browser=${{ matrix.browser }} --timeout 90 + - name: Test Reference count + run: pytest tests/test_reference_count_async.py --browser=${{ matrix.browser }} + - name: Test Wheel Installation + run: pytest tests/test_installation.py --browser=${{ matrix.browser }} + - name: Test Generation Scripts + run: pytest tests/test_generation_scripts.py --browser=${{ matrix.browser }} - name: Test Sync API if: matrix.os != 'ubuntu-latest' - run: pytest -vv tests/sync --browser=${{ matrix.browser }} --timeout 90 + run: pytest tests/sync --browser=${{ matrix.browser }} --timeout 90 - name: Test Sync API if: matrix.os == 'ubuntu-latest' - run: xvfb-run pytest -vv tests/sync --browser=${{ matrix.browser }} --timeout 90 + run: xvfb-run pytest tests/sync --browser=${{ matrix.browser }} --timeout 90 - name: Test Async API if: matrix.os != 'ubuntu-latest' - run: pytest -vv tests/async --browser=${{ matrix.browser }} --timeout 90 + run: pytest tests/async --browser=${{ matrix.browser }} --timeout 90 - name: Test Async API if: matrix.os == 'ubuntu-latest' - run: xvfb-run pytest -vv tests/async --browser=${{ matrix.browser }} --timeout 90 + run: xvfb-run pytest tests/async --browser=${{ matrix.browser }} --timeout 90 stable: name: Stable @@ -148,27 +152,3 @@ jobs: - name: Test Async API if: matrix.os == 'ubuntu-latest' run: xvfb-run pytest -vv tests/async --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90 - - test-package-installations: - name: Test package installations - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v2 - - name: Set up Node.js - uses: actions/setup-node@v1 - with: - node-version: 12.x - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r local-requirements.txt - pip install -e . - python setup.py bdist_wheel - python -m playwright install-deps - - name: Test package installation - run: bash buildbots/test-package-installations.sh diff --git a/buildbots/assets/stub.py b/buildbots/assets/stub.py deleted file mode 100644 index 74a8f38a9..000000000 --- a/buildbots/assets/stub.py +++ /dev/null @@ -1,9 +0,0 @@ -from playwright.sync_api import sync_playwright - -with sync_playwright() as p: - for browser_type in [p.chromium, p.firefox, p.webkit]: - browser = browser_type.launch() - page = browser.new_page() - page.set_content("

Test 123

") - page.screenshot(path=f"{browser_type.name}.png") - browser.close() diff --git a/buildbots/assets/test-reference-count-async.py b/buildbots/assets/test-reference-count-async.py deleted file mode 100644 index a732e16ad..000000000 --- a/buildbots/assets/test-reference-count-async.py +++ /dev/null @@ -1,45 +0,0 @@ -import asyncio -import gc - -import objgraph -import pandas as pd - -from playwright.async_api import async_playwright - - -def print_memory_objects() -> None: - gc.collect() - - df_dicts = pd.DataFrame() - df_dicts["dicts"] = objgraph.by_type("dict") - df_dicts["pw_types"] = df_dicts["dicts"].apply(lambda x: x.get("_type")) - - head = df_dicts["pw_types"].value_counts().head(20) - - for class_name, reference_count in head.items(): - print(class_name, reference_count) - - -async def main() -> None: - async with async_playwright() as p: - browser = await p.chromium.launch() - page = await browser.new_page() - await page.goto("https://example.com") - - page.on("dialog", lambda dialog: dialog.dismiss()) - for _ in range(100): - await page.evaluate("""async () => alert()""") - - await page.route("**/", lambda route, request: route.fulfill(body="OK")) - - for i in range(100): - response = await page.evaluate("""async () => (await fetch("/")).text()""") - assert response == "OK" - - await browser.close() - print_memory_objects() - - print("PW-OK") - - -asyncio.run(main()) diff --git a/buildbots/test-package-installations.sh b/buildbots/test-package-installations.sh deleted file mode 100644 index d9b6ea698..000000000 --- a/buildbots/test-package-installations.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -tmpdir=$(mktemp -d) -base_dir=$(pwd) -set -e - -# Cleanup to ensure we start fresh -echo "Deleting driver and browsers from base installation" -rm -rf driver -rm -rf playwright -rm -rf ~/.cache/ms-playwright - -cp buildbots/assets/stub.py "$tmpdir/main.py" - -cd $tmpdir -echo "Creating virtual environment" -virtualenv env -source env/bin/activate -echo "Installing Playwright Python via Wheel" -pip install "$(echo $base_dir/dist/playwright*manylinux1*.whl)" -echo "Installing browsers" -python -m playwright install -echo "Running basic tests" -python "main.py" -cd - - -test -f "$tmpdir/chromium.png" -test -f "$tmpdir/firefox.png" -test -f "$tmpdir/webkit.png" -echo "Passed package installation tests successfully" diff --git a/buildbots/test-reference-count.sh b/buildbots/test-reference-count.sh deleted file mode 100644 index 900e436fa..000000000 --- a/buildbots/test-reference-count.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -set -e - -NOT_ALLOWED_REFERENCES=("Dialog" "Request" "Route") - -OUTPUT=$(python buildbots/assets/test-reference-count-async.py) - -if [[ "$OUTPUT" != *"PW-OK"* ]]; then - echo "Script did not run successfully!" - echo "Output: $OUTPUT" - exit 1 -fi - -for CLASS_NAME in ${NOT_ALLOWED_REFERENCES[*]}; do - echo "Checking $CLASS_NAME" - if [[ "$OUTPUT" == *"$CLASS_NAME"* ]]; then - echo "There are $CLASS_NAME references in the memory!" - echo "Output: $OUTPUT" - exit 1 - fi - echo "Check $CLASS_NAME passed" -done - -echo "-> Reference count assertions passed!" diff --git a/setup.cfg b/setup.cfg index 56a0babea..0329788c0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,5 @@ [tool:pytest] +addopts = -rsx -vv markers = skip_browser only_browser diff --git a/tests/assets/client.py b/tests/assets/client.py new file mode 100644 index 000000000..dceae28c8 --- /dev/null +++ b/tests/assets/client.py @@ -0,0 +1,33 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path + +from playwright.sync_api import Playwright, sync_playwright + + +def main(playwright: Playwright) -> None: + for browser_type in [playwright.chromium, playwright.firefox, playwright.webkit]: + browser = browser_type.launch() + page = browser.new_page() + page.goto("https://example.com") + here = Path(__file__).parent.resolve() + page.screenshot(path=here / f"{browser_type.name}.png") + page.close() + browser.close() + + +if __name__ == "__main__": + with sync_playwright() as p: + main(p) diff --git a/tests/test_generation_scripts.py b/tests/test_generation_scripts.py index eeda5773f..6534c7d4f 100644 --- a/tests/test_generation_scripts.py +++ b/tests/test_generation_scripts.py @@ -1,29 +1,39 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License") +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import sys from io import StringIO from unittest.mock import patch import pytest -CAN_RUN_GENERATION_SCRIPT = sys.version_info >= (3, 8) - -if CAN_RUN_GENERATION_SCRIPT: - from scripts.generate_async_api import main as generate_async_api - from scripts.generate_sync_api import main as generate_sync_api +pytestmark = pytest.mark.skipif( + sys.version_info < (3, 9), reason="requires python3.9 or higher" +) -@pytest.mark.skipif( - not CAN_RUN_GENERATION_SCRIPT, reason="requires python3.8 or higher" -) @patch("sys.stderr", new_callable=StringIO) @patch("sys.stdout", new_callable=StringIO) def test_generate_sync_api(stdout, stderr): + from scripts.generate_sync_api import main as generate_sync_api + generate_sync_api() -@pytest.mark.skipif( - not CAN_RUN_GENERATION_SCRIPT, reason="requires python3.8 or higher" -) @patch("sys.stderr", new_callable=StringIO) @patch("sys.stdout", new_callable=StringIO) def test_generate_async_api(stdout, stderr): + from scripts.generate_async_api import main as generate_async_api + generate_async_api() diff --git a/tests/test_installation.py b/tests/test_installation.py new file mode 100644 index 000000000..c203d2129 --- /dev/null +++ b/tests/test_installation.py @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License") +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import shutil +import subprocess +import sys +from pathlib import Path +from venv import EnvBuilder + + +def test_install(tmp_path: Path): + env = EnvBuilder(with_pip=True) + env.create(env_dir=tmp_path) + context = env.ensure_directories(tmp_path) + root = Path(__file__).parent.parent.resolve() + if sys.platform == "win32": + wheelpath = list((root / "dist").glob("playwright*win_amd64*.whl"))[0] + elif sys.platform == "linux": + wheelpath = list((root / "dist").glob("playwright*manylinux1*.whl"))[0] + elif sys.platform == "darwin": + wheelpath = list((root / "dist").glob("playwright*macosx_10_*.whl"))[0] + subprocess.check_output( + [ + context.env_exe, + "-m", + "pip", + "install", + str(wheelpath), + ] + ) + environ = os.environ.copy() + environ["PLAYWRIGHT_BROWSERS_PATH"] = str(tmp_path) + subprocess.check_output( + [context.env_exe, "-m", "playwright", "install"], env=environ + ) + shutil.copyfile(root / "tests" / "assets" / "client.py", tmp_path / "main.py") + subprocess.check_output([context.env_exe, str(tmp_path / "main.py")], env=environ) + assert (tmp_path / "chromium.png").exists() + assert (tmp_path / "firefox.png").exists() + assert (tmp_path / "webkit.png").exists() diff --git a/tests/test_reference_count_async.py b/tests/test_reference_count_async.py new file mode 100644 index 000000000..3e42cfd66 --- /dev/null +++ b/tests/test_reference_count_async.py @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License") +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import gc + +import objgraph +import pandas as pd +import pytest + +from playwright.async_api import async_playwright + + +@pytest.mark.asyncio +async def test_memory_objects() -> None: + async with async_playwright() as p: + browser = await p.chromium.launch() + page = await browser.new_page() + await page.goto("https://example.com") + + page.on("dialog", lambda dialog: dialog.dismiss()) + for _ in range(100): + await page.evaluate("""async () => alert()""") + + await page.route("**/", lambda route, _: route.fulfill(body="OK")) + + for _ in range(100): + response = await page.evaluate("""async () => (await fetch("/")).text()""") + assert response == "OK" + + await browser.close() + + gc.collect() + + df_dicts = pd.DataFrame() + df_dicts["dicts"] = objgraph.by_type("dict") + df_dicts["pw_types"] = df_dicts["dicts"].apply(lambda x: x.get("_type")) + + head = df_dicts["pw_types"].value_counts().head(20) + assert "Dialog" not in head.items() + assert "Request" not in head.items() + assert "Route" not in head.items()