Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ jobs:
name: Type Checker
run: bazel run //py:mypy

lint:
name: Lint
uses: ./.github/workflows/bazel.yml
with:
name: Lint
run: bazel run //py:ruff -- --check

unit-tests:
name: Unit Tests
needs: build
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,7 @@ namespace :all do
end

Bazel.execute('run', [], '//py:mypy')
Bazel.execute('run', [], '//py:ruff')
Bazel.execute('run', [], '//rb:steep')
shellcheck = Bazel.execute('build', [], '@multitool//tools/shellcheck')
Bazel.execute('run', ['--', '-shellcheck', shellcheck], '@multitool//tools/actionlint:cwd')
Expand Down
15 changes: 6 additions & 9 deletions common/devtools/convert_protocol_to_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@


def main(argv):
parser = argparse.ArgumentParser(
description=("Converts from .pdl to .json by invoking the pdl Python module.")
)
parser = argparse.ArgumentParser(description=("Converts from .pdl to .json by invoking the pdl Python module."))
parser.add_argument(
"--map_binary_to_string",
type=bool,
Expand All @@ -28,14 +26,13 @@ def main(argv):
parser.add_argument("json_file", help="The .json output file write.")
args = parser.parse_args(argv)
file_name = os.path.normpath(args.pdl_file)
input_file = open(file_name, "r")
pdl_string = input_file.read()
with open(file_name) as input_file:
pdl_string = input_file.read()

protocol = pdl.loads(pdl_string, file_name, args.map_binary_to_string)
input_file.close()

output_file = open(os.path.normpath(args.json_file), "w")
json.dump(protocol, output_file, indent=4, separators=(",", ": "))
output_file.close()
with open(os.path.normpath(args.json_file), "w") as output_file:
json.dump(protocol, output_file, indent=4, separators=(",", ": "))


if __name__ == "__main__":
Expand Down
25 changes: 7 additions & 18 deletions common/devtools/pdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function
from collections import OrderedDict
import json
import re
import sys
from collections import OrderedDict
from typing import Any

description = ""
Expand All @@ -24,9 +23,7 @@
]


def assignType(
item: dict, type: str, is_array: bool = False, map_binary_to_string: bool = False
) -> None:
def assignType(item: dict, type: str, is_array: bool = False, map_binary_to_string: bool = False) -> None:
if is_array:
item["type"] = "array"
item["items"] = OrderedDict()
Expand Down Expand Up @@ -59,9 +56,7 @@ def createItem(
return result


def parse(
data: str, file_name: str, map_binary_to_string: bool = False
) -> OrderedDict[str, Any]:
def parse(data: str, file_name: str, map_binary_to_string: bool = False) -> OrderedDict[str, Any]:
protocol = OrderedDict()
protocol["version"] = OrderedDict()
protocol["domains"] = []
Expand Down Expand Up @@ -91,9 +86,7 @@ def parse(

match = re.compile(r"^(experimental )?(deprecated )?domain (.*)").match(line)
if match:
domain = createItem(
{"domain": match.group(3)}, match.group(1), match.group(2)
)
domain = createItem({"domain": match.group(3)}, match.group(1), match.group(2))
protocol["domains"].append(domain)
continue

Expand All @@ -116,9 +109,7 @@ def parse(
domain["types"].append(item)
continue

match = re.compile(
r"^ (experimental )?(deprecated )?(command|event) (.*)"
).match(line)
match = re.compile(r"^ (experimental )?(deprecated )?(command|event) (.*)").match(line)
if match:
list = []
if match.group(3) == "command":
Expand Down Expand Up @@ -185,14 +176,12 @@ def parse(
enumliterals.append(trimLine)
continue

print("Error in %s:%s, illegal token: \t%s" % (file_name, i, line))
print(f"Error in {file_name}:{i}, illegal token: \t{line}")
sys.exit(1)
return protocol


def loads(
data: str, file_name: str, map_binary_to_string: bool = False
) -> OrderedDict[str, Any] | Any:
def loads(data: str, file_name: str, map_binary_to_string: bool = False) -> OrderedDict[str, Any] | Any:
if file_name.endswith(".pdl"):
return parse(data, file_name, map_binary_to_string)
return json.loads(data)
19 changes: 9 additions & 10 deletions dotnet/private/generate_resources_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Each identifier becomes a const string in ResourceUtilities class.
The content is emitted as a C# raw string literal using 5-quotes.

TODO:
Todo:
It would be nice to convert this small single-file utility to .NET10/C#,
so it would work like `dotnet run generate_resources.cs -- <args>`.
Meaning .NET developers can easily support it.
Expand All @@ -18,17 +18,16 @@
import argparse
import os
import sys
from typing import List, Tuple


def parse_args(argv: List[str]) -> argparse.Namespace:
def parse_args(argv: list[str]) -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--output", required=True)
parser.add_argument("--input", action="append", default=[], help="IDENT=path")
return parser.parse_args(argv)


def parse_input_spec(spec: str) -> Tuple[str, str]:
def parse_input_spec(spec: str) -> tuple[str, str]:
if "=" not in spec:
raise ValueError(f"Invalid --input value, expected IDENT=path, got: {spec}")
ident, path = spec.split("=", 1)
Expand All @@ -41,10 +40,10 @@ def parse_input_spec(spec: str) -> Tuple[str, str]:
return ident, path


def generate(output: str, inputs: List[Tuple[str, str]]) -> None:
props: List[str] = []
def generate(output: str, inputs: list[tuple[str, str]]) -> None:
props: list[str] = []
for prop_name, path in inputs:
with open(path, "r", encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:
content = f.read()
# Use a C# raw string literal with five quotes. For a valid raw
# literal, the content must start on a new line and the closing
Expand All @@ -58,7 +57,7 @@ def generate(output: str, inputs: List[Tuple[str, str]]) -> None:
literal = '"""""\n' + content + '\n"""""'
props.append(f" internal const string {prop_name} = {literal};")

lines: List[str] = []
lines: list[str] = []
lines.append("// <auto-generated />")
lines.append("namespace OpenQA.Selenium.Internal;")
lines.append("")
Expand All @@ -74,9 +73,9 @@ def generate(output: str, inputs: List[Tuple[str, str]]) -> None:
f.write("\n".join(lines))


def main(argv: List[str]) -> int:
def main(argv: list[str]) -> int:
args = parse_args(argv)
inputs: List[Tuple[str, str]] = []
inputs: list[tuple[str, str]] = []
for spec in args.input:
ident, path = parse_input_spec(spec)
inputs.append((ident, path))
Expand Down
83 changes: 38 additions & 45 deletions javascript/private/gen_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ def write_atom_literal(out, name, contents, lang, utf8):
elif "java" == lang:
line_format = ' .append\("{}")\n'
else:
raise RuntimeError("Unknown language: %s " % lang)
raise RuntimeError(f"Unknown language: {lang} ")

name = get_atom_name(name)

if "cc" == lang or "hh" == lang:
char_type = "char" if utf8 else "wchar_t"
out.write("const %s* const %s[] = {\n" % (char_type, name))
out.write(f"const {char_type}* const {name}[] = {{\n")
elif "java" == lang:
out.write(" %s(new StringBuilder()\n" % name)
out.write(f" {name}(new StringBuilder()\n")
else:
raise RuntimeError("Unknown language: %s " % lang)
raise RuntimeError(f"Unknown language: {lang} ")

# Make the header file play nicely in a terminal: limit lines to 80
# characters, but make sure we don't cut off a line in the middle
Expand All @@ -76,73 +76,68 @@ def write_atom_literal(out, name, contents, lang, utf8):


def generate_header(file_name, out, js_map, just_declare, utf8):
define_guard = "WEBDRIVER_%s" % os.path.basename(file_name.upper()).replace(
".", "_"
)
define_guard = "WEBDRIVER_{}".format(os.path.basename(file_name.upper()).replace(".", "_"))
include_stddef = "" if utf8 else "\n#include <stddef.h> // For wchar_t."
out.write(
"""%s
f"""{_copyright}

/* AUTO GENERATED - DO NOT EDIT BY HAND */
#ifndef %s
#define %s
%s
#ifndef {define_guard}
#define {define_guard}
{include_stddef}
#include <string> // For std::(w)string.

namespace webdriver {
namespace atoms {
namespace webdriver {{
namespace atoms {{

"""
% (_copyright, define_guard, define_guard, include_stddef)
)

string_type = "std::string" if utf8 else "std::wstring"
char_type = "char" if utf8 else "wchar_t"

for name, file in js_map.items():
if just_declare:
out.write("extern const %s* const %s[];\n" % (char_type, name.upper()))
out.write(f"extern const {char_type}* const {name.upper()}[];\n")
else:
contents = open(file, "r").read()
contents = open(file).read()
write_atom_literal(out, name, contents, "hh", utf8)

out.write(
"""
static inline %s asString(const %s* const atom[]) {
%s source;
for (int i = 0; atom[i] != NULL; i++) {
f"""
static inline {string_type} asString(const {char_type}* const atom[]) {{
{string_type} source;
for (int i = 0; atom[i] != NULL; i++) {{
source += atom[i];
}
}}
return source;
}
}}

} // namespace atoms
} // namespace webdriver
}} // namespace atoms
}} // namespace webdriver

#endif // %s
#endif // {define_guard}
"""
% (string_type, char_type, string_type, define_guard)
)


def generate_cc_source(out, js_map, utf8):
out.write(
"""%s
f"""{_copyright}

/* AUTO GENERATED - DO NOT EDIT BY HAND */

#include <stddef.h> // For NULL.
#include "atoms.h"

namespace webdriver {
namespace atoms {
namespace webdriver {{
namespace atoms {{

"""
% _copyright
)

for name, file in js_map.items():
contents = open(file, "r").read()
contents = open(file).read()
write_atom_literal(out, name, contents, "cc", utf8)

out.write("""
Expand All @@ -162,37 +157,35 @@ def generate_java_source(file_name, out, preamble, js_map):
out.write(preamble)
out.write("")
out.write(
"""
public enum %s {
f"""
public enum {class_name} {{

// AUTO GENERATED - DO NOT EDIT BY HAND
"""
% class_name
)

for name, file in js_map.items():
contents = open(file, "r").read()
contents = open(file).read()
write_atom_literal(out, name, contents, "java", True)

out.write(
"""
f"""
;
private final String value;

public String getValue() {
public String getValue() {{
return value;
}
}}

public String toString() {
public String toString() {{
return getValue();
}
}}

%s(String value) {
{class_name}(String value) {{
this.value = value;
}
}
}}
}}
"""
% class_name
)


Expand All @@ -216,7 +209,7 @@ def main(argv=[]):
elif "java" == lang:
generate_java_source(file_name, out, preamble, js_map)
else:
raise RuntimeError("Unknown lang: %s" % lang)
raise RuntimeError(f"Unknown lang: {lang}")


if __name__ == "__main__":
Expand Down
10 changes: 10 additions & 0 deletions py/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ load("//py:defs.bzl", "generate_devtools", "py_test_suite")
load("//py/private:browsers.bzl", "BROWSERS")
load("//py/private:import.bzl", "py_import")

exports_files(
["pyproject.toml"],
visibility = ["//py:__subpackages__"],
)

py_binary(
name = "selenium-release",
srcs = [
Expand Down Expand Up @@ -661,3 +666,8 @@ py_binary(
requirement("mypy"),
],
)

alias(
name = "ruff",
actual = "//py/private:ruff",
)
Loading