2023-12-05 22:22:46 -06:00
|
|
|
#!/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()
|
2025-05-17 08:26:02 -04:00
|
|
|
parser.add_argument(
|
|
|
|
|
"--chrome_channel", default="Stable", help="Set the Chrome channel"
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
channel = args.chrome_channel
|
|
|
|
|
|
|
|
|
|
r = http.request(
|
2025-05-17 08:26:02 -04:00
|
|
|
"GET",
|
|
|
|
|
f"https://chromiumdash.appspot.com/fetch_releases?channel={channel}&num=1&platform=Mac,Linux",
|
2023-12-05 22:22:46 -06:00
|
|
|
)
|
|
|
|
|
all_versions = json.loads(r.data)
|
|
|
|
|
# use the same milestone for all Chrome releases, so pick the lowest
|
2025-05-17 08:26:02 -04:00
|
|
|
milestone = min(
|
|
|
|
|
[version["milestone"] for version in all_versions if version["milestone"]]
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
r = http.request(
|
2025-05-17 08:26:02 -04:00
|
|
|
"GET",
|
|
|
|
|
"https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json",
|
2023-12-05 22:22:46 -06:00
|
|
|
)
|
|
|
|
|
versions = json.loads(r.data)["versions"]
|
|
|
|
|
|
|
|
|
|
return sorted(
|
2025-05-17 08:26:02 -04:00
|
|
|
filter(lambda v: v["version"].split(".")[0] == str(milestone), versions),
|
|
|
|
|
key=lambda v: parse(v["version"]),
|
2023-12-05 22:22:46 -06:00
|
|
|
)[-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)
|
|
|
|
|
|
|
|
|
|
|
2025-10-15 21:43:06 +02:00
|
|
|
def flatten_browser_pdl(file_path, chrome_version):
|
2025-10-16 18:02:18 +02:00
|
|
|
"""Preserves the version block and concatenates all included domain .pdl files."""
|
2025-10-15 21:43:06 +02:00
|
|
|
with open(file_path, "r") as file:
|
|
|
|
|
content = file.read()
|
2025-10-16 18:02:18 +02:00
|
|
|
# Extract version block
|
|
|
|
|
version_match = re.search(r"(version\s+major\s+\d+\s+minor\s+\d+)", content)
|
|
|
|
|
version_block = version_match.group(1) + "\n\n" if version_match else ""
|
2025-10-15 21:43:06 +02:00
|
|
|
# Find all include lines
|
|
|
|
|
includes = re.findall(r"include domains/([A-Za-z0-9_]+\.pdl)", content)
|
|
|
|
|
base_url = f"https://raw.githubusercontent.com/chromium/chromium/{chrome_version}/third_party/blink/public/devtools_protocol/domains/"
|
|
|
|
|
concatenated = ""
|
|
|
|
|
for domain_file in includes:
|
|
|
|
|
url = base_url + domain_file
|
|
|
|
|
response = http.request("GET", url)
|
|
|
|
|
concatenated += response.data.decode("utf-8") + "\n"
|
2025-10-16 18:02:18 +02:00
|
|
|
# Overwrite the file with version block + concatenated domains
|
2025-10-15 21:43:06 +02:00
|
|
|
with open(file_path, "w") as file:
|
2025-10-16 18:02:18 +02:00
|
|
|
file.write(version_block + concatenated)
|
2025-10-15 21:43:06 +02:00
|
|
|
|
|
|
|
|
|
2023-12-05 22:22:46 -06:00
|
|
|
def add_pdls(chrome_milestone):
|
2025-05-17 08:26:02 -04:00
|
|
|
source_dir = (
|
|
|
|
|
root_dir / f"common/devtools/chromium/v{previous_chrome(chrome_milestone)}"
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
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)
|
|
|
|
|
|
2025-03-12 13:40:24 -07:00
|
|
|
if not target_dir.is_dir() or not any(target_dir.iterdir()):
|
2023-12-05 22:22:46 -06:00
|
|
|
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",
|
|
|
|
|
)
|
|
|
|
|
|
2025-10-15 21:43:06 +02:00
|
|
|
flatten_browser_pdl(
|
|
|
|
|
f"{target_dir}/browser_protocol.pdl", chrome_milestone["version"]
|
|
|
|
|
)
|
|
|
|
|
|
2023-12-05 22:22:46 -06:00
|
|
|
deps_content = http.request(
|
2025-05-17 08:26:02 -04:00
|
|
|
"GET",
|
|
|
|
|
f"https://raw.githubusercontent.com/chromium/chromium/{chrome_milestone['version']}/DEPS",
|
2023-12-05 22:22:46 -06:00
|
|
|
).data.decode("utf-8")
|
2025-05-17 08:26:02 -04:00
|
|
|
v8_revision = (
|
|
|
|
|
[line for line in deps_content.split("\n") if "v8_revision" in line][0]
|
|
|
|
|
.split(": ")[1]
|
|
|
|
|
.strip("',")
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
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)}"
|
|
|
|
|
|
2024-01-22 14:25:51 -06:00
|
|
|
if old_dir.is_dir():
|
|
|
|
|
shutil.rmtree(old_dir)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2024-01-22 14:25:51 -06:00
|
|
|
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)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2024-01-22 14:25:51 -06:00
|
|
|
for file in target_dir.iterdir():
|
2025-05-17 08:26:02 -04:00
|
|
|
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)
|
|
|
|
|
)
|
2024-01-22 14:25:51 -06:00
|
|
|
file.rename(target_dir / new_filename)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2024-01-22 14:25:51 -06:00
|
|
|
subprocess.run(["git", "add", str(target_dir / "*")], cwd=root_dir)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
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:
|
2025-05-17 08:26:02 -04:00
|
|
|
replace_in_file(
|
|
|
|
|
file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_dotnet(chrome_milestone):
|
|
|
|
|
create_new_chrome_files("dotnet/src/webdriver/DevTools", chrome_milestone)
|
|
|
|
|
|
|
|
|
|
files = [
|
|
|
|
|
root_dir / "dotnet/selenium-dotnet-version.bzl",
|
2025-06-25 18:28:45 +02:00
|
|
|
root_dir / "dotnet/src/webdriver/Selenium.WebDriver.csproj",
|
2023-12-05 22:22:46 -06:00
|
|
|
root_dir / "dotnet/src/webdriver/DevTools/DevToolsDomains.cs",
|
|
|
|
|
]
|
|
|
|
|
for file in files:
|
2025-05-17 08:26:02 -04:00
|
|
|
replace_in_file(
|
|
|
|
|
file, old_chrome(chrome_milestone), new_chrome(chrome_milestone)
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2025-05-17 08:26:02 -04:00
|
|
|
files = [
|
|
|
|
|
root_dir / "dotnet/test/common/CustomDriverConfigs/StableChannelChromeDriver.cs"
|
|
|
|
|
]
|
2023-12-05 22:22:46 -06:00
|
|
|
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:
|
2025-05-17 08:26:02 -04:00
|
|
|
replace_in_file(
|
|
|
|
|
file, previous_chrome(chrome_milestone), new_chrome(chrome_milestone)
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
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"
|
2025-05-17 08:26:02 -04:00
|
|
|
replace_in_file(
|
|
|
|
|
file,
|
|
|
|
|
rf"{previous_chrome(chrome_milestone)}\.[0-9]*",
|
|
|
|
|
f"{new_chrome(chrome_milestone)}.0",
|
|
|
|
|
True,
|
|
|
|
|
)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2023-12-06 22:53:09 -06:00
|
|
|
subprocess.run(["bundle", "install"], cwd=root_dir / "rb", check=True)
|
2023-12-05 22:22:46 -06:00
|
|
|
|
2025-05-17 08:26:02 -04:00
|
|
|
|
2023-12-05 22:22:46 -06:00
|
|
|
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):
|
2025-03-25 14:28:37 +01:00
|
|
|
file = root_dir / "javascript/selenium-webdriver/BUILD.bazel"
|
2023-12-05 22:22:46 -06:00
|
|
|
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)
|
2024-01-22 14:25:51 -06:00
|
|
|
|
2025-05-17 08:26:02 -04:00
|
|
|
print(
|
|
|
|
|
f"adding CDP {new_chrome(chrome_milestone)} and removing {old_chrome(chrome_milestone)}"
|
|
|
|
|
)
|