diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 71fa7455798f0..173e4b077d22a 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -84,6 +84,7 @@ jobs: TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} SE_AVOID_STATS: true + SE_CACHE_PATH: $RUNNER_TEMP/selenium steps: - name: Checkout source tree uses: actions/checkout@v4 diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index dcd9a199e8e78..54b378a8a9634 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -2,22 +2,24 @@ name: CI - Python on: workflow_call: + inputs: + targets: + required: false + type: string + default: '' + run-full-suite: + required: false + type: boolean + default: true workflow_dispatch: permissions: contents: read jobs: - build: - name: Build - uses: ./.github/workflows/bazel.yml - with: - name: Build - run: | - bazel build //py:selenium-wheel //py:selenium-sdist - docs: name: Documentation + if: ${{ inputs.run-full-suite }} runs-on: ubuntu-latest steps: - name: Checkout source tree @@ -38,6 +40,7 @@ jobs: typing: name: Type Checker + if: ${{ inputs.run-full-suite }} runs-on: ubuntu-latest steps: - name: Checkout source tree @@ -58,7 +61,7 @@ jobs: unit-tests: name: Unit Tests - needs: build + if: ${{ inputs.run-full-suite }} uses: ./.github/workflows/bazel.yml strategy: fail-fast: false @@ -71,31 +74,64 @@ jobs: python-version: ${{ matrix.python-version }} run: bazel test --local_test_jobs 1 //py:unit - remote-tests: - name: Remote Tests - needs: build + requirements: + name: Requirements Lock + if: ${{ inputs.run-full-suite }} uses: ./.github/workflows/bazel.yml with: - name: Integration Tests Remote - browser: yes - run: | - bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-remote + name: Requirements Lock + os: ubuntu + python-version: '3.10' + run: bazel test //py:requirements.test + + + filter-targets: + name: Filter Targets + runs-on: ubuntu-latest + outputs: + targets: ${{ steps.filter.outputs.targets }} + steps: + - name: Filter Python targets + id: filter + shell: bash + run: | + targets="${{ inputs.targets }}" + filtered=() + + for t in $targets; do + [[ "$t" == //py* ]] && filtered+=("$t") + done + + if [ ${#filtered[@]} -eq 0 ]; then + echo "targets=//py/..." >> "$GITHUB_OUTPUT" + else + echo "targets=${filtered[*]}" >> "$GITHUB_OUTPUT" + fi browser-tests: name: Browser Tests - needs: build + needs: filter-targets uses: ./.github/workflows/bazel.yml strategy: fail-fast: false matrix: - browser: [chrome, firefox, chrome-bidi, edge] + browser: [chrome, firefox] + bidi: [true, false] os: [windows] include: - browser: safari + bidi: false os: macos with: - name: Integration Tests (${{ matrix.browser }}) + name: Browser Tests (${{ matrix.browser }}${{ matrix.bidi && '-bidi' || '' }}) browser: ${{ matrix.browser }} os: ${{ matrix.os }} - run: | - bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-${{ matrix.browser }} + run: > + bazel test + --keep_going + --build_tests_only + --flaky_test_attempts 3 + --local_test_jobs 1 + --test_size_filters large + --test_tag_filters=${{ matrix.bidi && format('{0}-bidi', matrix.browser) || format('{0},-bidi,-remote', matrix.browser) }} + ${{ needs.filter-targets.outputs.targets }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab0f535c85c66..9e496d6c8a5b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,12 +76,20 @@ jobs: name: Python needs: check uses: ./.github/workflows/ci-python.yml + with: + targets: ${{ needs.check.outputs.targets }} + run-full-suite: >- + ${{ + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + github.event_name == 'workflow_call' || + contains(github.event.pull_request.title, '[py]') + }} if: > github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call' || contains(needs.check.outputs.targets, '//py') || - contains(join(github.event.commits.*.message), '[py]') || contains(github.event.pull_request.title, '[py]') ruby: diff --git a/py/BUILD.bazel b/py/BUILD.bazel index 8ab5a697cda78..c45c34c022e4f 100644 --- a/py/BUILD.bazel +++ b/py/BUILD.bazel @@ -499,7 +499,11 @@ BROWSER_TESTS = { ] + BROWSERS[browser]["args"], data = BROWSERS[browser]["data"], env_inherit = ["DISPLAY"], - tags = ["no-sandbox"] + BROWSERS[browser]["tags"], + tags = [ + "bidi", + "no-sandbox", + "%s-bidi" % browser, + ] + BROWSERS[browser]["tags"], deps = [ ":init-tree", ":selenium", @@ -541,7 +545,7 @@ BROWSER_TESTS = { "no-sandbox", "remote", "%s-remote" % browser, - ], + ] + BROWSERS[browser]["tags"], deps = [ ":init-tree", ":selenium", diff --git a/py/test/selenium/webdriver/common/bidi_emulation_tests.py b/py/test/selenium/webdriver/common/bidi_emulation_tests.py index c40d7aea5b183..a3142c43ed0f2 100644 --- a/py/test/selenium/webdriver/common/bidi_emulation_tests.py +++ b/py/test/selenium/webdriver/common/bidi_emulation_tests.py @@ -14,6 +14,8 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +import sys + import pytest from selenium.webdriver.common.bidi.emulation import ( @@ -117,6 +119,7 @@ def test_emulation_initialized(driver): assert isinstance(driver.emulation, Emulation) +@pytest.mark.xfail_firefox(reason="Firefox BiDi geolocation override does not work with contexts parameter") def test_set_geolocation_override_with_coordinates_in_context(driver, pages): context_id = driver.current_window_handle pages.load("blank.html") @@ -132,6 +135,10 @@ def test_set_geolocation_override_with_coordinates_in_context(driver, pages): assert abs(result["accuracy"] - coords.accuracy) < 1.0, f"Accuracy mismatch: {result['accuracy']}" +@pytest.mark.xfail_firefox( + condition=sys.platform == "win32", + reason="Firefox + Windows: navigator.geolocation.getCurrentPosition returns None", +) def test_set_geolocation_override_with_coordinates_in_user_context(driver, pages): # Create a user context user_context = driver.browser.create_user_context() @@ -156,6 +163,10 @@ def test_set_geolocation_override_with_coordinates_in_user_context(driver, pages driver.browser.remove_user_context(user_context) +@pytest.mark.xfail_firefox( + condition=sys.platform == "win32", + reason="Firefox + Windows: navigator.geolocation.getCurrentPosition returns None", +) def test_set_geolocation_override_all_coords(driver, pages): context_id = driver.current_window_handle pages.load("blank.html") @@ -181,6 +192,10 @@ def test_set_geolocation_override_all_coords(driver, pages): driver.browsing_context.close(context_id) +@pytest.mark.xfail_firefox( + condition=sys.platform == "win32", + reason="Firefox + Windows: navigator.geolocation.getCurrentPosition returns None", +) def test_set_geolocation_override_with_multiple_contexts(driver, pages): # Create two browsing contexts context1_id = driver.browsing_context.create(type=WindowTypes.TAB) @@ -214,6 +229,10 @@ def test_set_geolocation_override_with_multiple_contexts(driver, pages): driver.browsing_context.close(context2_id) +@pytest.mark.xfail_firefox( + condition=sys.platform == "win32", + reason="Firefox + Windows: navigator.geolocation.getCurrentPosition returns None", +) def test_set_geolocation_override_with_multiple_user_contexts(driver, pages): # Create two user contexts user_context1 = driver.browser.create_user_context()