diff --git a/.bazelrc b/.bazelrc index 4c9ebcfd307a6..281fcd02ad7d5 100644 --- a/.bazelrc +++ b/.bazelrc @@ -39,6 +39,8 @@ build --nobuild_runfile_links # More JS magic build --experimental_allow_unresolved_symlinks +# Avoid a warning about directory tracking being unsound +startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1 # Required for faster TS builds build --@aspect_rules_ts//ts:skipLibCheck=always diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000000000..8f13b55a4e290 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,6 @@ +changelog: + exclude: + labels: + -dependencies + authors: + - selenium-ci diff --git a/.github/workflows/ci-javascript.yml b/.github/workflows/ci-javascript.yml deleted file mode 100644 index 38f61cd0911cf..0000000000000 --- a/.github/workflows/ci-javascript.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: CI - JavaScript - -on: - workflow_call: - workflow_dispatch: - -jobs: - build: - name: Build - uses: ./.github/workflows/bazel.yml - with: - name: Build - cache-key: javascript-build - run: bazel build //javascript/node/selenium-webdriver:selenium-webdriver - - browser-tests: - name: Browser Tests - needs: build - uses: ./.github/workflows/bazel.yml - strategy: - fail-fast: false - matrix: - browser: - - chrome - - firefox - with: - name: Browser Tests (${{ matrix.browser }}) - browser: ${{ matrix.browser }} - cache-key: javascript-${{matrix.browser}}-browser-tests - run: > - bazel test - --flaky_test_attempts 3 - --test_tag_filters ${{ matrix.browser }} - --local_test_jobs 1 - //javascript/node/... diff --git a/.github/workflows/ci-ruby.yml b/.github/workflows/ci-ruby.yml index 79f941a23485b..419e17df5065c 100644 --- a/.github/workflows/ci-ruby.yml +++ b/.github/workflows/ci-ruby.yml @@ -74,12 +74,9 @@ jobs: - edge - firefox os: - - ubuntu - windows - macos exclude: - - browser: edge - os: ubuntu - browser: edge os: macos with: @@ -94,7 +91,7 @@ jobs: --local_test_jobs 1 --test_size_filters large --test_tag_filters ${{ matrix.browser }} - ${{ matrix.os != 'windows' && '--pin_browsers=true' || '' }} + ${{ matrix.os != 'windows' && '--pin_browsers' || '' }} //rb/spec/... integration-tests-remote: @@ -107,10 +104,6 @@ jobs: include: - browser: edge os: windows - - browser: chrome - os: ubuntu - - browser: firefox - os: ubuntu with: name: Remote Tests (${{ matrix.browser }}, ${{ matrix.os }}) browser: ${{ matrix.browser }} @@ -124,5 +117,5 @@ jobs: --local_test_jobs 1 --test_size_filters large --test_tag_filters ${{ matrix.browser }}-remote - ${{ matrix.os != 'windows' && '--pin_browsers=true' || '' }} + ${{ matrix.os != 'windows' && '--pin_browsers' || '' }} //rb/spec/... diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2df302b754c39..2175fe47d3b96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,17 +59,6 @@ jobs: contains(join(github.event.commits.*.message), '[java]') || contains(github.event.pull_request.title, '[java]') - javascript: - name: JavaScript - needs: check - uses: ./.github/workflows/ci-javascript.yml - if: > - github.event_name == 'schedule' || - github.event_name == 'workflow_dispatch' || - contains(needs.check.outputs.targets, '//javascript') || - contains(join(github.event.commits.*.message), '[js]') || - contains(github.event.pull_request.title, '[js]') - python: name: Python needs: check diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 42d6a0e0c0f31..fb2d19a97a272 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -36,7 +36,7 @@ jobs: git checkout -b release-${{ github.event.inputs.version }} - name: Update Rust Version run: | - ./go rust:version + ./go rust:version[${{ github.event.inputs.version }}] ./go rust:version:commit - name: Push changes uses: ad-m/github-push-action@master diff --git a/.github/workflows/stage-release.yml b/.github/workflows/stage-release.yml index ee722d1773eb5..5f4eccb69d477 100644 --- a/.github/workflows/stage-release.yml +++ b/.github/workflows/stage-release.yml @@ -57,3 +57,9 @@ jobs: generate_release_notes: true prerelease: false files: build/dist/*.* + + update-documentation: + needs: github-release + uses: ./.github/workflows/update-documentation.yml + with: + tag: selenium-${{ needs.github-release.outputs.version }} diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 02166dc7a6d34..7e2e5efee541f 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -8,78 +8,247 @@ on: required: true type: string + workflow_call: + inputs: + tag: + required: true + type: string + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: + determine-language: + runs-on: ubuntu-latest + outputs: + language: ${{ steps.get-language.outputs.language }} + steps: + - name: Parse language from tag + id: get-language + run: | + tag=${{ inputs.tag }} + language=$(echo $tag | awk -F'-' '{print $NF}') + if [[ ! "$language" =~ ^(java|ruby|python|dotnet|node)$ ]]; then + language="all" + fi + echo "language=$language" > $GITHUB_OUTPUT + java-docs: runs-on: ubuntu-latest + needs: determine-language steps: - name: Checkout the tag uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} + - name: Prep git + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" - name: Setup Java uses: actions/setup-java@v3 with: java-version: 17 distribution: 'temurin' - name: Update Documentation - run: ./go java:docs[true] + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'java' + run: ./go java:docs + - name: Create patch for changes + run: | + git format-patch -1 HEAD --stdout > java-docs.patch + - name: Upload patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'java' + uses: actions/upload-artifact@v2 + with: + name: java-docs-patch + path: java-docs.patch ruby-docs: runs-on: ubuntu-latest + needs: determine-language steps: - name: Checkout the tag uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} + - name: Prep git + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" - name: Setup Java uses: actions/setup-java@v3 with: java-version: 17 distribution: 'temurin' - name: Update Documentation - run: ./go ruby:docs[true] + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'ruby' + run: ./go rb:docs + - name: Create patch for changes + run: | + git format-patch -1 HEAD --stdout > ruby-docs.patch + - name: Upload patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'ruby' + uses: actions/upload-artifact@v2 + with: + name: ruby-docs-patch + path: ruby-docs.patch python-docs: + needs: determine-language runs-on: ubuntu-latest steps: - name: Checkout the tag uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} + - name: Prep git + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" - name: Set up Python 3.8 uses: actions/setup-python@v4 with: python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox - name: Update Documentation - run: ./go py:docs[true] + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'python' + run: ./go py:docs + - name: Create patch for changes + run: | + git format-patch -1 HEAD --stdout > python-docs.patch + - name: Upload patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'python' + uses: actions/upload-artifact@v2 + with: + name: python-docs-patch + path: python-docs.patch dotnet-docs: + needs: determine-language runs-on: ubuntu-latest steps: - name: Checkout the tag uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} + - name: Prep git + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" - name: Install specific version of DocFX tool # Pinning to 2.75.3 to avoid breaking changes in newer versions # See https://github.com/dotnet/docfx/issues/9855 run: dotnet tool install --global --version 2.75.3 docfx - name: Update Documentation - run: ./go dotnet:docs[true] + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'dotnet' + run: ./go dotnet:docs + - name: Create patch for changes + run: | + git format-patch -1 HEAD --stdout > dotnet-docs.patch + - name: Upload patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'dotnet' + uses: actions/upload-artifact@v2 + with: + name: dotnet-docs-patch + path: dotnet-docs.patch node-docs: + needs: determine-language runs-on: ubuntu-latest steps: - name: Checkout the tag uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} + - name: Prep git + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" - name: Install npm dependencies run: | npm install npm install --prefix javascript/node/selenium-webdriver - name: Update Documentation - run: ./go node:docs[true] + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'node' + run: ./go node:docs + - name: Create patch for changes + run: | + git format-patch -1 HEAD --stdout > node-docs.patch + - name: Upload patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'node' + uses: actions/upload-artifact@v2 + with: + name: node-docs-patch + path: node-docs.patch + + merge-patches: + runs-on: ubuntu-latest + needs: [java-docs, ruby-docs, python-docs, dotnet-docs, node-docs] + steps: + - name: Checkout documentation branch + uses: actions/checkout@v4 + with: + ref: 'gh-pages' + - name: Create and checkout new branch + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" + git checkout -b api-docs-${{ inputs.tag }} + - name: Download Java patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'java' + uses: actions/download-artifact@v2 + with: + name: java-docs-patch + path: patches/ + - name: Download Ruby patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'ruby' + uses: actions/download-artifact@v2 + with: + name: ruby-docs-patch + path: patches/ + - name: Download Python patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'python' + uses: actions/download-artifact@v2 + with: + name: python-docs-patch + path: patches/ + - name: Download .NET patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'dotnet' + uses: actions/download-artifact@v2 + with: + name: dotnet-docs-patch + path: patches/ + - name: Download Node patch + if: needs.determine-language.outputs.language == 'all' || needs.determine-language.outputs.language == 'node' + uses: actions/download-artifact@v2 + with: + name: node-docs-patch + path: patches/ + - name: Apply patches + run: | + for patch in patches/*.patch; do + git am < "$patch" + done + - name: Push Branch + run: git push origin api-docs-${{ inputs.tag }} + - name: Documentation Pull Request + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.SELENIUM_CI_TOKEN }} + author: Selenium CI Bot + delete-branch: true + branch: api-docs-${{ inputs.tag }} + base: gh-pages + title: Update documentation for ${{ inputs.tag }} + body: | + This PR updates the API documentation for all bindings + based on the provided tag name. + + - Auto-generated by [create-pull-request][1] + + [1]: https://github.com/peter-evans/create-pull-request + labels: documentation + draft: false diff --git a/.gitignore b/.gitignore index d0e0fbe7d099c..259551ffd4482 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ py/selenium/webdriver/remote/findElements.js py/selenium/webdriver/remote/getAttribute.js py/selenium/webdriver/remote/isDisplayed.js py/docs/build/ +py/docs/source/**/* py/build/ py/LICENSE py/pytestdebug.log diff --git a/.skipped-tests b/.skipped-tests index 15dc35e335372..16f00c9b99235 100644 --- a/.skipped-tests +++ b/.skipped-tests @@ -19,17 +19,38 @@ -//javascript/atoms:test-chrome -//javascript/atoms:test-edge -//javascript/atoms:test-firefox-beta +-//javascript/node/selenium-webdriver:test-bidi-network-test.js-chrome +-//javascript/node/selenium-webdriver:test-builder-test.js-chrome +-//javascript/node/selenium-webdriver:test-builder-test.js-firefox +-//javascript/node/selenium-webdriver:test-chrome-devtools-test.js-chrome +-//javascript/node/selenium-webdriver:test-chrome-options-test.js-chrome +-//javascript/node/selenium-webdriver:test-chrome-service-test.js-chrome +-//javascript/node/selenium-webdriver:test-firefox-options-test.js-firefox +-//javascript/node/selenium-webdriver:test-lib-capabilities-test.js-chrome -//py:test-chrome-test/selenium/webdriver/chrome/chrome_launcher_tests.py -//py:test-chrome-test/selenium/webdriver/chrome/chrome_service_tests.py -//py:test-chrome-test/selenium/webdriver/chrome/proxy_tests.py -//rb/spec/integration/selenium/webdriver/chrome:service-chrome +-//rb/spec/integration/selenium/webdriver/chrome:service-chrome-bidi +-//rb/spec/integration/selenium/webdriver/chrome:service-chrome-remote -//rb/spec/integration/selenium/webdriver/edge:service-edge +-//rb/spec/integration/selenium/webdriver/edge:service-edge-bidi +-//rb/spec/integration/selenium/webdriver/edge:service-edge-remote +-//rb/spec/integration/selenium/webdriver/firefox:driver-firefox-beta-bidi -//rb/spec/integration/selenium/webdriver/firefox:service-firefox -//rb/spec/integration/selenium/webdriver/firefox:service-firefox-beta --//rb/spec/integration/selenium/webdriver:element-chrome --//rb/spec/integration/selenium/webdriver/chrome:service-chrome-bidi --//rb/spec/integration/selenium/webdriver/edge:service-edge-bidi --//rb/spec/integration/selenium/webdriver/firefox:service-firefox-bidi -//rb/spec/integration/selenium/webdriver/firefox:service-firefox-beta-bidi +-//rb/spec/integration/selenium/webdriver/firefox:service-firefox-beta-remote +-//rb/spec/integration/selenium/webdriver/firefox:service-firefox-bidi +-//rb/spec/integration/selenium/webdriver/firefox:service-firefox-remote +-//rb/spec/integration/selenium/webdriver/remote:driver-chrome-remote +-//rb/spec/integration/selenium/webdriver/remote:driver-edge-remote +-//rb/spec/integration/selenium/webdriver/remote:driver-firefox-beta-remote +-//rb/spec/integration/selenium/webdriver/remote:driver-firefox-remote +-//rb/spec/integration/selenium/webdriver/remote:element-chrome-remote +-//rb/spec/integration/selenium/webdriver/remote:element-edge-remote +-//rb/spec/integration/selenium/webdriver/remote:element-firefox-beta-remote +-//rb/spec/integration/selenium/webdriver/remote:element-firefox-remote +-//rb/spec/integration/selenium/webdriver:element-chrome -//rb/spec/integration/selenium/webdriver:element-chrome-bidi --//rb/spec/integration/selenium/webdriver/firefox:driver-firefox-beta-bidi +-//rb/spec/integration/selenium/webdriver:element-chrome-remote diff --git a/AUTHORS b/AUTHORS index 39da6a60b9d47..11a8283f1f12c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -150,6 +150,7 @@ Chris Martin Chris Mohr Chris Stringer Chris Ward +Christian Ansel <36796016+ChrstnAnsl@users.noreply.github.com> Christian Biesinger Christian Clauss Christopher Buttkus @@ -242,6 +243,8 @@ Dylan Reichstadt Dylan Semler Earlopain <14981592+Earlopain@users.noreply.github.com> Eberhard Beilharz +Ed Manlove +Ed Manlove Edi Weissmann Edirin Atumah Eduardo Wermuth @@ -344,6 +347,7 @@ ifland Ilya Kozhevnikov Ilyas Bayraktar Immanuel Hayden +Indomitable Innokenty Shuvalov Isaac A. Murchie Isaul Vargas @@ -646,6 +650,7 @@ nvonop Oboleninov Anton Oleg Höfling Oleg Ridchenko <73664101+oleg-rd@users.noreply.github.com> +Oleksandr Kulychok Oleksandr Kulychok Oleksii Olivier SCHNEIDER diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa82517e05b5e..80b6ecaf11662 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,6 +89,40 @@ to check that your approach aligns with the project's ideas. Nothing is more frustrating than seeing your hard work go to waste because your vision doesn't align with the project's. +#### Dependencies Managed by Bazel + +##### Java + +Edit `MODULE.bazel`, and either update or add the dependency you want +using the regular maven coordinates to the `maven.install` with the +name `maven`. Once done, run `REPIN=1 bazel run @maven//:pin` to +update the lock file, create a PR and check the change in. + +##### JS + +We use `pnpm` for JS development in the project, and we also use [pnpm +workspaces](https://pnpm.io/workspaces). Take a look at the top-level +`pnpm-workspace.yaml` file to find them all, but the main thing to +know is that each of the workspaces has its own `package.json`. You +can add dependencies to specific workspaces either by using `pnpm` +installed on your local machine, or by executing: + +```shell +# Example of adding a dep to the JS webdriver bindings +cd javascript/node/selenium-webdriver +bazel run javascript:pnpm -- install my-amazing-dep --dir $PWD +``` + +This will install the dependency using the same version of `pnpm` we +build the project with for a single JS project. + +To update all dependencies in the tree to the latest version: + +`bazel run javascript:pnpm -- -r up --dir $PWD` + +This will also update the lock file, so once a change is made, create +a PR and commit all the changed files. + #### License Headers Every file in the Selenium project must carry the following license diff --git a/MODULE.bazel b/MODULE.bazel index ad934d7d09e27..bde71eecb9491 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -39,7 +39,10 @@ linter.configure( linter.register(name = "rust-rustfmt") node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") -node.toolchain(node_version = "18.17.0") +node.toolchain(node_version = "20.9.0") + +pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm", dev_dependency = True) +use_repo(pnpm, "pnpm") npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm") npm.npm_translate_lock( @@ -162,7 +165,7 @@ maven.install( name = "maven", artifacts = [ "com.beust:jcommander:1.82", - "com.github.javaparser:javaparser-core:3.26.0", + "com.github.javaparser:javaparser-core:3.26.1", "com.github.spotbugs:spotbugs:4.8.6", "com.github.stephenc.jcip:jcip-annotations:1.0-1", "com.google.code.gson:gson:2.11.0", @@ -174,7 +177,7 @@ maven.install( "com.graphql-java:graphql-java:20.2", "com.graphql-java:java-dataloader:3.2.0", "dev.failsafe:failsafe:3.3.2", - "io.grpc:grpc-context:1.64.0", + "io.grpc:grpc-context:1.65.1", "io.lettuce:lettuce-core:6.3.2.RELEASE", "io.netty:netty-buffer:4.1.111.Final", "io.netty:netty-codec-http:4.1.111.Final", @@ -183,35 +186,35 @@ maven.install( "io.netty:netty-handler:4.1.111.Final", "io.netty:netty-handler-proxy:4.1.111.Final", "io.netty:netty-transport:4.1.111.Final", - "io.opentelemetry:opentelemetry-api:1.39.0", - "io.opentelemetry:opentelemetry-context:1.39.0", - "io.opentelemetry:opentelemetry-exporter-logging:1.39.0", - "io.opentelemetry:opentelemetry-sdk:1.39.0", - "io.opentelemetry:opentelemetry-sdk-common:1.39.0", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.39.0", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.39.0", - "io.opentelemetry:opentelemetry-sdk-testing:1.39.0", - "io.opentelemetry:opentelemetry-sdk-trace:1.39.0", + "io.opentelemetry:opentelemetry-api:1.40.0", + "io.opentelemetry:opentelemetry-context:1.40.0", + "io.opentelemetry:opentelemetry-exporter-logging:1.40.0", + "io.opentelemetry:opentelemetry-sdk:1.40.0", + "io.opentelemetry:opentelemetry-sdk-common:1.40.0", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.40.0", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.40.0", + "io.opentelemetry:opentelemetry-sdk-testing:1.40.0", + "io.opentelemetry:opentelemetry-sdk-trace:1.40.0", "io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha", "io.ous:jtoml:2.0.0", "it.ozimov:embedded-redis:0.7.3", - "net.bytebuddy:byte-buddy:1.14.17", - "org.htmlunit:htmlunit-core-js:4.2.0", + "net.bytebuddy:byte-buddy:1.14.18", + "org.htmlunit:htmlunit-core-js:4.3.0", "org.apache.commons:commons-exec:1.4.0", "org.apache.logging.log4j:log4j-core:2.23.1", - "org.assertj:assertj-core:3.26.0", + "org.assertj:assertj-core:3.26.3", "org.bouncycastle:bcpkix-jdk18on:1.78.1", "org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5", "org.hsqldb:hsqldb:2.7.3", - "org.junit.jupiter:junit-jupiter-api:5.10.2", - "org.junit.jupiter:junit-jupiter-engine:5.10.2", - "org.junit.jupiter:junit-jupiter-params:5.10.2", - "org.junit.platform:junit-platform-launcher:1.10.2", - "org.junit.platform:junit-platform-reporting:1.10.2", - "org.junit.platform:junit-platform-commons:1.10.2", - "org.junit.platform:junit-platform-engine:1.10.2", + "org.junit.jupiter:junit-jupiter-api:5.10.3", + "org.junit.jupiter:junit-jupiter-engine:5.10.3", + "org.junit.jupiter:junit-jupiter-params:5.10.3", + "org.junit.platform:junit-platform-launcher:1.10.3", + "org.junit.platform:junit-platform-reporting:1.10.3", + "org.junit.platform:junit-platform-commons:1.10.3", + "org.junit.platform:junit-platform-engine:1.10.3", "org.mockito:mockito-core:5.12.0", - "org.redisson:redisson:3.31.0", + "org.redisson:redisson:3.33.0", "org.slf4j:slf4j-api:2.0.13", "org.slf4j:slf4j-jdk14:2.0.13", "org.zeromq:jeromq:0.6.0", diff --git a/README.md b/README.md index 6ebfda3fbf20f..e5ef14de8c4f4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI](https://github.com/SeleniumHQ/selenium/actions/workflows/ci.yml/badge.svg?branch=trunk&event=schedule)](https://github.com/SeleniumHQ/selenium/actions/workflows/ci.yml) -Selenium +Selenium Logo Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically diff --git a/Rakefile b/Rakefile index 177e78f97279a..0dc22a2ebeba1 100644 --- a/Rakefile +++ b/Rakefile @@ -99,7 +99,7 @@ JAVA_RELEASE_TARGETS = %w[ //java/src/org/openqa/selenium/chromium:chromium.publish //java/src/org/openqa/selenium/devtools/v125:v125.publish //java/src/org/openqa/selenium/devtools/v126:v126.publish - //java/src/org/openqa/selenium/devtools/v124:v124.publish + //java/src/org/openqa/selenium/devtools/v127:v127.publish //java/src/org/openqa/selenium/devtools/v85:v85.publish //java/src/org/openqa/selenium/edge:edge.publish //java/src/org/openqa/selenium/firefox:firefox.publish @@ -466,10 +466,7 @@ namespace :node do raise end - unless arguments[:skip_update] - puts 'Updating JavaScript documentation' - puts update_gh_pages ? 'JavaScript Docs updated!' : 'JavaScript Doc update cancelled' - end + update_gh_pages unless arguments[:skip_update] end desc 'Update JavaScript changelog' @@ -563,10 +560,7 @@ namespace :py do raise end - unless arguments[:skip_update] - puts 'Updating Python documentation' - puts update_gh_pages ? 'Python Docs updated!' : 'Python Doc update cancelled' - end + update_gh_pages unless arguments[:skip_update] end desc 'Install Python wheel locally' @@ -700,10 +694,7 @@ namespace :rb do FileUtils.mkdir_p('build/docs/api') FileUtils.cp_r('bazel-bin/rb/docs.sh.runfiles/_main/docs/api/rb/.', 'build/docs/api/rb') - unless arguments[:skip_update] - puts 'Updating Ruby documentation' - puts update_gh_pages ? 'Ruby Docs updated!' : 'Ruby Doc update cancelled' - end + update_gh_pages unless arguments[:skip_update] end desc 'Update Ruby changelog' @@ -810,10 +801,7 @@ namespace :dotnet do end end - unless arguments[:skip_update] - puts 'Updating .NET documentation' - puts update_gh_pages ? '.NET Docs updated!' : '.NET Doc update cancelled' - end + update_gh_pages unless arguments[:skip_update] end desc 'Update .NET changelog' @@ -896,10 +884,7 @@ namespace :java do task :docs, [:skip_update] do |_task, arguments| Rake::Task['javadocs'].invoke - unless arguments[:skip_update] - puts 'Updating Java documentation' - puts update_gh_pages ? 'Java Docs updated!' : 'Java Doc update cancelled' - end + update_gh_pages unless arguments[:skip_update] end desc 'Update Maven dependencies' @@ -1013,16 +998,13 @@ end namespace :all do desc 'Update all API Documentation' task :docs do - FileUtils.rm_rf('build/docs/api') - Rake::Task['java:docs'].invoke(true) Rake::Task['py:docs'].invoke(true) Rake::Task['rb:docs'].invoke(true) Rake::Task['dotnet:docs'].invoke(true) Rake::Task['node:docs'].invoke(true) - puts 'Updating All API Docs' - puts update_gh_pages ? 'AP Docs updated!' : 'API Doc update cancelled' + update_gh_pages end desc 'Build all artifacts for all language bindings' @@ -1052,28 +1034,35 @@ namespace :all do Rake::Task['rb:release'].invoke(*args) Rake::Task['dotnet:release'].invoke(*args) Rake::Task['node:release'].invoke(*args) - Rake::Task['all:docs'].invoke + + # TODO: Update this so it happens in each language, but does not commit Rake::Task['all:version'].invoke('nightly') puts 'Committing nightly version updates' - commit!('update versions to nightly', ['java/version.bzl', + commit!('update versions to nightly', ['dotnet/selenium-dotnet-version.bzl', + 'java/version.bzl', + 'javascript/node/selenium-webdriver/BUILD.bazel', + 'javascript/node/selenium-webdriver/package.json', + 'py/docs/source/conf.py', + 'py/selenium/webdriver/__init__.py', + 'py/selenium/__init__.py', + 'py/BUILD.bazel', + 'py/setup.py', 'rb/lib/selenium/webdriver/version.rb', 'rb/Gemfile.lock', - 'py/setup.py', - 'py/BUILD.bazel', - 'py/selenium/__init__.py', - 'py/selenium/webdriver/__init__.py', - 'py/docs/source/conf.py', - 'rust/BUILD.bazel', - 'rust/Cargo.Bazel.lock', - 'rust/Cargo.lock', - 'rust/Cargo.toml']) + 'package-lock.json']) print 'Do you want to push the committed changes? (Y/n): ' response = $stdin.gets.chomp.downcase @git.push if %w[y yes].include?(response) end + task :lint do + ext = /mswin|msys|mingw|cygwin|bccwin|wince|emc/.match?(RbConfig::CONFIG['host_os']) ? 'ps1' : 'sh' + sh "./scripts/format.#{ext}", verbose: true + Rake::Task['py:lint'].invoke + end + desc 'Update everything in preparation for a release' task :prepare, [:version, :channel] do |_task, arguments| chrome_channel = arguments[:channel] || 'Stable' @@ -1107,6 +1096,7 @@ namespace :all do commit!('Update authors file', ['AUTHORS']) # Note that this does not include Rust version changes that are handled in separate rake:version task + # TODO: These files are all defined in other tasks; remove duplication Rake::Task['all:version'].invoke(version) commit!("FIX CHANGELOGS BEFORE MERGING!\n\nUpdate versions and change logs to release Selenium #{java_version}", ['dotnet/CHANGELOG', @@ -1158,70 +1148,19 @@ def updated_version(current, desired = nil, nightly = nil) end end -# TODO: make this less insane -# rubocop:disable all def update_gh_pages - origin_reference = @git.current_branch - origin_reference ||= begin - # This allows updating docs from a tagged commit instead of a branch - puts 'commit is not at HEAD, checking for matching tag' - tag = @git.tags.detect { |t| t.sha == @git.revparse('HEAD') } - tag ? tag.name : raise(StandardError, 'Must be on a tagged commit or at the HEAD of a branch to update API Docs') - end - - puts 'Checking out gh-pages' - begin - @git.checkout('gh-pages') - rescue Git::FailedError => e - # This happens when the working directory is not clean and things need to be stashed or committed - line = e.message.lines[2].gsub('output: "error: ', '') - puts line.gsub('\t', "\t").split('\n')[0...-2].join("\n") - # TODO: we could offer to automatically fix with a stash, but there may be edge cases - print 'Manually Fix and Retry? (Y/n):' - response = $stdin.gets.chomp.downcase - return false unless %w[y yes].include?(response) - - retry - end - - puts 'Updating gh-pages branch from upstream repository' - begin - @git.pull - rescue Git::FailedError => e - # This happens when upstream is not already set - line = e.message.lines[2].gsub('output: "error: ', '') - puts line.gsub('\t', "\t").split('\n').delete_if(&:empty?)[-2...-1].join("\n") - print 'Manually Fix and Retry? (Y/n):' - response = $stdin.gets.chomp.downcase - return restore_git(origin_reference) unless %w[y yes].include?(response) - - retry - end + @git.fetch('origin', {ref: 'gh-pages'}) + @git.checkout('gh-pages', force: true) %w[java rb py dotnet javascript].each do |language| next unless Dir.exist?("build/docs/api/#{language}") && !Dir.empty?("build/docs/api/#{language}") - puts "Deleting #{language} directory in docs/api since corresponding directory in build/docs/api is not empty" FileUtils.rm_rf("docs/api/#{language}") - puts 'Moving documentation files from untracked build directory to tracked docs directory' FileUtils.mv("build/docs/api/#{language}", "docs/api/#{language}") - end - - print 'Do you want to commit the changes? (Y/n): ' - response = $stdin.gets.chomp.downcase - return restore_git(origin_reference) unless %w[y yes].include?(response) - - puts 'Committing changes' - commit!('updating all API docs', ['docs/api/']) - puts 'Pushing changes to upstream repository' - @git.push - - puts "Checking out originating branch/tag — #{origin_reference}" - @git.checkout(origin_reference) - true + commit!("updating #{language} API docs", ["docs/api/#{language}/"]) + end end -# rubocop:disable all def restore_git(origin_reference) puts 'Stashing docs changes for gh-pages' @@ -1245,14 +1184,14 @@ def previous_tag(current_version, language = nil) else minor_version = (version[1].to_i - 1) tags = @git.tags.map(&:name) - tag = language ? tags.reverse.find { |tag| tag.match?(/selenium-4\.#{minor_version}.*-#{language}/) } : nil + tag = language ? tags.reverse.find { |t| t.match?(/selenium-4\.#{minor_version}.*-#{language}/) } : nil tag || "selenium-#{[[version[0]], minor_version, '0'].join('.')}" end end def update_changelog(version, language, path, changelog, header) tag = previous_tag(version, language) - log = `git --no-pager log #{tag}...HEAD --pretty=format:">>> %B" --reverse #{path}` + log = `git --no-pager log #{tag}...HEAD --pretty=format:"--> %B" --reverse #{path}` commits = log.split('>>>').map { |entry| lines = entry.split("\n") lines.reject! { |line| line.match?(/^(----|Co-authored|Signed-off)/) || line.empty? } diff --git a/common/devtools/chromium/v124/BUILD.bazel b/common/devtools/chromium/v127/BUILD.bazel similarity index 100% rename from common/devtools/chromium/v124/BUILD.bazel rename to common/devtools/chromium/v127/BUILD.bazel diff --git a/common/devtools/chromium/v124/browser_protocol.pdl b/common/devtools/chromium/v127/browser_protocol.pdl similarity index 96% rename from common/devtools/chromium/v124/browser_protocol.pdl rename to common/devtools/chromium/v127/browser_protocol.pdl index c05c02fd4a99f..0db3f7a0e9824 100644 --- a/common/devtools/chromium/v124/browser_protocol.pdl +++ b/common/devtools/chromium/v127/browser_protocol.pdl @@ -475,6 +475,12 @@ experimental domain Animation # Animation that was started. Animation animation + # Event for animation that has been updated. + event animationUpdated + parameters + # Animation that was updated. + Animation animation + # Audits domain allows investigation of page violations and possible improvements. experimental domain Audits depends on Network @@ -616,6 +622,8 @@ experimental domain Audits CoopSandboxedIFrameCannotNavigateToCoopPage CorpNotSameOrigin CorpNotSameOriginAfterDefaultedToSameOriginByCoep + CorpNotSameOriginAfterDefaultedToSameOriginByDip + CorpNotSameOriginAfterDefaultedToSameOriginByCoepAndDip CorpNotSameSite # Details for a request that has been blocked with the BLOCKED_BY_RESPONSE @@ -735,6 +743,32 @@ experimental domain Audits NoRegisterOsSourceHeader NoRegisterOsTriggerHeader + type SharedDictionaryError extends string + enum + UseErrorCrossOriginNoCorsRequest + UseErrorDictionaryLoadFailure + UseErrorMatchingDictionaryNotUsed + UseErrorUnexpectedContentDictionaryHeader + WriteErrorCossOriginNoCorsRequest + WriteErrorDisallowedBySettings + WriteErrorExpiredResponse + WriteErrorFeatureDisabled + WriteErrorInsufficientResources + WriteErrorInvalidMatchField + WriteErrorInvalidStructuredHeader + WriteErrorNavigationRequest + WriteErrorNoMatchField + WriteErrorNonListMatchDestField + WriteErrorNonSecureContext + WriteErrorNonStringIdField + WriteErrorNonStringInMatchDestList + WriteErrorNonStringMatchField + WriteErrorNonTokenTypeField + WriteErrorRequestAborted + WriteErrorShuttingDown + WriteErrorTooLongIdField + WriteErrorUnsupportedType + # Details for issues around "Attribution Reporting API" usage. # Explainer: https://github.com/WICG/attribution-reporting-api type AttributionReportingIssueDetails extends object @@ -761,6 +795,11 @@ experimental domain Audits string url optional SourceCodeLocation location + type SharedDictionaryIssueDetails extends object + properties + SharedDictionaryError sharedDictionaryError + AffectedRequest request + type GenericIssueErrorType extends string enum CrossOriginPortalPostMessageError @@ -812,6 +851,9 @@ experimental domain Audits type CookieDeprecationMetadataIssueDetails extends object properties array of string allowedSites + number optOutPercentage + boolean isOptOutTopLevel + CookieOperation operation type ClientHintIssueReason extends string enum @@ -870,6 +912,10 @@ experimental domain Audits SilentMediationFailure ThirdPartyCookiesBlocked NotSignedInWithIdp + MissingTransientUserActivation + ReplacedByButtonMode + RelyingPartyOriginIsOpaque + TypeNotMatching type FederatedAuthUserInfoRequestIssueDetails extends object properties @@ -964,6 +1010,7 @@ experimental domain Audits StylesheetLoadingIssue FederatedAuthUserInfoRequestIssue PropertyRuleIssue + SharedDictionaryIssue # This struct holds a list of optional fields with additional information # specific to the kind of issue. When adding a new issue code, please also @@ -990,6 +1037,7 @@ experimental domain Audits optional StylesheetLoadingIssueDetails stylesheetLoadingIssueDetails optional PropertyRuleIssueDetails propertyRuleIssueDetails optional FederatedAuthUserInfoRequestIssueDetails federatedAuthUserInfoRequestIssueDetails + optional SharedDictionaryIssueDetails sharedDictionaryIssueDetails # A unique id for a DevTools inspector issue. Allows other entities (e.g. # exceptions, CDP message, console messages, etc.) to reference an issue. @@ -1051,6 +1099,21 @@ experimental domain Audits parameters InspectorIssue issue +# Defines commands and events for browser extensions. Available if the client +# is connected using the --remote-debugging-pipe flag and +# the --enable-unsafe-extension-debugging flag is set. +experimental domain Extensions + # Installs an unpacked extension from the filesystem similar to + # --load-extension CLI flags. Returns extension ID once the extension + # has been installed. + command loadUnpacked + parameters + # Absolute file path. + string path + returns + # Extension id. + string id + # Defines commands and events for Autofill. experimental domain Autofill type CreditCard extends object @@ -2570,11 +2633,14 @@ domain DOM marker backdrop selection + search-text target-text spelling-error grammar-error highlight first-line-inherited + scroll-marker + scroll-marker-group scrollbar scrollbar-thumb scrollbar-button @@ -3074,6 +3140,20 @@ domain DOM # NodeIds of top layer elements array of NodeId nodeIds + # Returns the NodeId of the matched element according to certain relations. + experimental command getElementByRelation + parameters + # Id of the node from which to query the relation. + NodeId nodeId + # Type of relation to get. + enum relation + # Get the popover target for a given element. In this case, this given + # element can only be an HTMLFormControlElement (,