| #!/usr/bin/env python |
| |
| import argparse |
| import json |
| import os |
| import re |
| import shutil |
| import subprocess |
| from pathlib import Path |
| |
| import urllib3 |
| from packaging.version import parse |
| |
| http = urllib3.PoolManager() |
| root_dir = Path(os.path.realpath(__file__)).parent.parent |
| |
| |
| def get_chrome_milestone(): |
| """This is the same method from pinned_browser. Use --chrome_channel=Beta if |
| using early stable release.""" |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| "--chrome_channel", default="Stable", help="Set the Chrome channel" |
| ) |
| args = parser.parse_args() |
| channel = args.chrome_channel |
| |
| r = http.request( |
| "GET", |
| f"https://chromiumdash.appspot.com/fetch_releases?channel={channel}&num=1&platform=Mac,Linux", |
| ) |
| all_versions = json.loads(r.data) |
| # use the same milestone for all Chrome releases, so pick the lowest |
| milestone = min( |
| [version["milestone"] for version in all_versions if version["milestone"]] |
| ) |
| r = http.request( |
| "GET", |
| "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", |
| ) |
| versions = json.loads(r.data)["versions"] |
| |
| return sorted( |
| filter(lambda v: v["version"].split(".")[0] == str(milestone), versions), |
| key=lambda v: parse(v["version"]), |
| )[-1] |
| |
| |
| def fetch_and_save(url, file_path): |
| response = http.request("GET", url) |
| with open(file_path, "wb") as file: |
| file.write(response.data) |
| |
| |
| def new_chrome(chrome_milestone): |
| return chrome_milestone["version"].split(".")[0] |
| |
| |
| def previous_chrome(chrome_milestone): |
| return str(int(new_chrome(chrome_milestone)) - 1) |
| |
| |
| def old_chrome(chrome_milestone): |
| return str(int(new_chrome(chrome_milestone)) - 3) |
| |
| |
| def add_pdls(chrome_milestone): |
| source_dir = ( |
| root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_milestone)}" |
| ) |
| target_dir = root_dir / f"common/devtools/chromium/v{new_chrome(chrome_milestone)}" |
| old_dir = root_dir / f"common/devtools/chromium/v{old_chrome(chrome_milestone)}" |
| |
| if os.path.isdir(old_dir): |
| shutil.rmtree(old_dir) |
| |
| if not target_dir.is_dir() or not any(target_dir.iterdir()): |
| os.makedirs(target_dir, exist_ok=True) |
| if os.path.isdir(source_dir): |
| shutil.copytree(source_dir, target_dir, dirs_exist_ok=True) |
| |
| fetch_and_save( |
| f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/third_party/blink/public/devtools_protocol/browser_protocol.pdl", |
| f"{target_dir}/browser_protocol.pdl", |
| ) |
| |
| deps_content = http.request( |
| "GET", |
| f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/DEPS", |
| ).data.decode("utf-8") |
| v8_revision = ( |
| [line for line in deps_content.split("\n") if "v8_revision" in line][0] |
| .split(": ")[1] |
| .strip("',") |
| ) |
| fetch_and_save( |
| f"https://raw.githubusercontent.com/v8/v8/{v8_revision}/include/js_protocol.pdl", |
| f"{target_dir}/js_protocol.pdl", |
| ) |
| |
| # javadocs does not like script tags |
| with open(f"{target_dir}/browser_protocol.pdl", "r+") as file: |
| script_replace = file.read().replace("`<script>`", "`script`") |
| file.seek(0) |
| file.write(script_replace) |
| file.truncate() |
| |
| subprocess.run(["git", "add", str(target_dir / "*")], cwd=root_dir) |
| |
| |
| def create_new_chrome_files(src_base, chrome_milestone): |
| """Java and .NET need to copy previous version directory into new version |
| directory.""" |
| source_dir = root_dir / f"{src_base}/v{previous_chrome(chrome_milestone)}" |
| target_dir = root_dir / f"{src_base}/v{new_chrome(chrome_milestone)}" |
| old_dir = root_dir / f"{src_base}/v{old_chrome(chrome_milestone)}" |
| |
| if old_dir.is_dir(): |
| shutil.rmtree(old_dir) |
| |
| if source_dir.is_dir() and any(source_dir.iterdir()): |
| os.makedirs(target_dir, exist_ok=True) |
| for item in source_dir.iterdir(): |
| shutil.copy(item, target_dir) |
| |
| for file in target_dir.iterdir(): |
| replace_in_file( |
| file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone) |
| ) |
| new_filename = file.name.replace( |
| previous_chrome(chrome_milestone), new_chrome(chrome_milestone) |
| ) |
| file.rename(target_dir / new_filename) |
| |
| subprocess.run(["git", "add", str(target_dir / "*")], cwd=root_dir) |
| |
| |
| def replace_in_file(file_path, old_string, new_string, is_regex=False): |
| with open(file_path, "r+") as file: |
| if not is_regex: |
| old_string = re.escape(old_string) |
| data = re.sub(old_string, new_string, file.read()) |
| file.seek(0) |
| file.write(data) |
| file.truncate() |
| |
| |
| def update_java(chrome_milestone): |
| create_new_chrome_files("java/src/org/openqa/selenium/devtools", chrome_milestone) |
| |
| files = [ |
| root_dir / "java/src/org/openqa/selenium/devtools/versions.bzl", |
| root_dir / "Rakefile", |
| ] |
| for file in files: |
| replace_in_file( |
| file, old_chrome(chrome_milestone), new_chrome(chrome_milestone) |
| ) |
| |
| |
| def update_dotnet(chrome_milestone): |
| create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_milestone) |
| |
| files = [ |
| root_dir / "dotnet/selenium-dotnet-version.bzl", |
| root_dir / "dotnet/src/webdriver/Selenium.WebDriver.csproj", |
| root_dir / "dotnet/src/webdriver/DevTools/DevToolsDomains.cs", |
| ] |
| for file in files: |
| replace_in_file( |
| file, old_chrome(chrome_milestone), new_chrome(chrome_milestone) |
| ) |
| |
| files = [ |
| root_dir / "dotnet/test/common/CustomDriverConfigs/StableChannelChromeDriver.cs" |
| ] |
| dir_path = root_dir / "dotnet/test/common/DevTools" |
| files.extend(str(file) for file in dir_path.glob("*") if file.is_file()) |
| for file in files: |
| replace_in_file( |
| file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone) |
| ) |
| |
| |
| def update_ruby(chrome_milestone): |
| file = root_dir / "rb/lib/selenium/devtools/BUILD.bazel" |
| replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) |
| |
| file = root_dir / "rb/lib/selenium/devtools/version.rb" |
| replace_in_file( |
| file, |
| rf"{previous_chrome(chrome_milestone)}\.[0-9]*", |
| f"{new_chrome(chrome_milestone)}.0", |
| True, |
| ) |
| |
| subprocess.run(["bundle", "install"], cwd=root_dir / "rb", check=True) |
| |
| |
| def update_python(chrome_milestone): |
| file = root_dir / "py/BUILD.bazel" |
| replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) |
| |
| |
| def update_js(chrome_milestone): |
| file = root_dir / "javascript/selenium-webdriver/BUILD.bazel" |
| replace_in_file(file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)) |
| |
| |
| if __name__ == "__main__": |
| chrome_milestone = get_chrome_milestone() |
| add_pdls(chrome_milestone) |
| update_java(chrome_milestone) |
| update_dotnet(chrome_milestone) |
| update_ruby(chrome_milestone) |
| update_python(chrome_milestone) |
| update_js(chrome_milestone) |
| |
| print( |
| f"adding CDP {new_chrome(chrome_milestone)} and removing {old_chrome(chrome_milestone)}" |
| ) |