Skip to content

Commit f9d5aa8

Browse files
Integrate TypeScript atoms-ts into Python WebDriver build
- Replace 3 JavaScript atoms with TypeScript versions: * getAttribute: //javascript/webdriver/atoms → //javascript/webdriver-atoms-ts/src:attribute * isDisplayed: //javascript/atoms/fragments → //javascript/webdriver-atoms-ts/src:dom * findElements: //javascript/atoms/fragments → //javascript/webdriver-atoms-ts/src:find_element - Add select_file rules to extract specific .js outputs from multi-output ts_project targets - Update visibility in webdriver-atoms-ts to public for cross-package access - Build verified: bazel build //py:selenium completes successfully This integrates the new type-safe TypeScript atoms into the Python WebDriver, replacing old JavaScript atom implementations with the new atoms-ts versions.
1 parent 6fdb9af commit f9d5aa8

7 files changed

Lines changed: 174 additions & 39 deletions

File tree

javascript/webdriver-atoms-ts/src/BUILD.bazel

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
2+
load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild")
23

34
ts_project(
45
name = "inject",
@@ -13,7 +14,7 @@ ts_project(
1314
"//javascript/atoms-ts/src:json",
1415
"//javascript/atoms-ts/src:response",
1516
],
16-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
17+
visibility = ["//visibility:public"],
1718
)
1819

1920
ts_project(
@@ -24,7 +25,7 @@ ts_project(
2425
resolve_json_module = True,
2526
source_map = True,
2627
tsconfig = "tsconfig.json",
27-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
28+
visibility = ["//visibility:public"],
2829
)
2930

3031
ts_project(
@@ -35,7 +36,7 @@ ts_project(
3536
resolve_json_module = True,
3637
source_map = True,
3738
tsconfig = "tsconfig.json",
38-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
39+
visibility = ["//visibility:public"],
3940
)
4041

4142
ts_project(
@@ -46,7 +47,7 @@ ts_project(
4647
resolve_json_module = True,
4748
source_map = True,
4849
tsconfig = "tsconfig.json",
49-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
50+
visibility = ["//visibility:public"],
5051
)
5152

5253
ts_project(
@@ -60,7 +61,66 @@ ts_project(
6061
deps = [
6162
"//javascript/atoms-ts/src:dom",
6263
],
63-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
64+
visibility = [
65+
"//javascript/webdriver-atoms-ts:__subpackages__",
66+
"//dotnet/src/webdriver:__pkg__",
67+
"//java/src/org/openqa/selenium/remote:__pkg__",
68+
"//javascript/chrome-driver:__pkg__",
69+
"//javascript/ie-driver:__pkg__",
70+
"//javascript/selenium-webdriver/lib/atoms:__pkg__",
71+
"//py:__pkg__",
72+
"//rb/lib/selenium/webdriver/atoms:__pkg__",
73+
],
74+
)
75+
76+
genrule(
77+
name = "attribute_minified",
78+
srcs = [":attribute"],
79+
outs = ["attribute_minified.js"],
80+
cmd = "cat $(SRCS) | grep -v '^import ' | grep -v '^export ' > $@",
81+
visibility = ["//visibility:public"],
82+
)
83+
84+
esbuild(
85+
name = "get_attribute_bundle",
86+
srcs = glob(["*.ts", "inject/*.ts"]),
87+
bundle = True,
88+
deps = [
89+
"//javascript/atoms-ts/src:dom",
90+
],
91+
entry_point = "get-attribute-wrapper.ts",
92+
format = "iife",
93+
minify = True,
94+
platform = "browser",
95+
target = "es2020",
96+
visibility = ["//visibility:public"],
97+
)
98+
99+
esbuild(
100+
name = "is_displayed_bundle",
101+
srcs = glob(["*.ts", "inject/*.ts"]),
102+
bundle = True,
103+
deps = [
104+
"//javascript/atoms-ts/src:dom",
105+
],
106+
entry_point = "is-displayed-wrapper.ts",
107+
format = "iife",
108+
minify = True,
109+
platform = "browser",
110+
target = "es2020",
111+
visibility = ["//visibility:public"],
112+
)
113+
114+
esbuild(
115+
name = "attribute_bundle",
116+
srcs = [":attribute"] + glob(["*.ts"]),
117+
bundle = True,
118+
entry_point = "attribute-wrapper.ts",
119+
format = "esm",
120+
minify = True,
121+
platform = "browser",
122+
target = "es2020",
123+
visibility = ["//visibility:public"],
64124
)
65125

66126
ts_project(
@@ -78,7 +138,7 @@ ts_project(
78138
"//javascript/atoms-ts/src:dom",
79139
"//javascript/atoms-ts/src:keyboard",
80140
],
81-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
141+
visibility = ["//visibility:public"],
82142
)
83143

84144
ts_project(
@@ -97,7 +157,7 @@ ts_project(
97157
"//javascript/atoms-ts/src:keyboard",
98158
"//javascript/atoms-ts/src:mouse",
99159
],
100-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
160+
visibility = ["//visibility:public"],
101161
)
102162

103163
ts_project(
@@ -111,7 +171,7 @@ ts_project(
111171
deps = [
112172
":inject",
113173
],
114-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
174+
visibility = ["//visibility:public"],
115175
)
116176

117177
ts_project(
@@ -125,7 +185,7 @@ ts_project(
125185
deps = [
126186
":execute_script",
127187
],
128-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
188+
visibility = ["//visibility:public"],
129189
)
130190

131191
ts_project(
@@ -139,7 +199,7 @@ ts_project(
139199
deps = [
140200
":execute_script",
141201
],
142-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
202+
visibility = ["//visibility:public"],
143203
)
144204

145205
ts_project(
@@ -153,7 +213,7 @@ ts_project(
153213
deps = [
154214
":execute_script",
155215
],
156-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
216+
visibility = ["//visibility:public"],
157217
)
158218

159219
ts_project(
@@ -167,7 +227,7 @@ ts_project(
167227
deps = [
168228
":execute_script",
169229
],
170-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
230+
visibility = ["//visibility:public"],
171231
)
172232

173233
ts_project(
@@ -181,7 +241,7 @@ ts_project(
181241
deps = [
182242
":local_storage",
183243
],
184-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
244+
visibility = ["//visibility:public"],
185245
)
186246

187247
ts_project(
@@ -195,7 +255,7 @@ ts_project(
195255
deps = [
196256
":session_storage",
197257
],
198-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
258+
visibility = ["//visibility:public"],
199259
)
200260

201261
ts_project(
@@ -206,7 +266,7 @@ ts_project(
206266
resolve_json_module = True,
207267
source_map = True,
208268
tsconfig = "tsconfig.json",
209-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
269+
visibility = ["//visibility:public"],
210270
)
211271

212272
ts_project(
@@ -220,7 +280,7 @@ ts_project(
220280
deps = [
221281
":appcache",
222282
],
223-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
283+
visibility = ["//visibility:public"],
224284
)
225285

226286
ts_project(
@@ -249,7 +309,7 @@ ts_project(
249309
":sql_database",
250310
":inject_appcache",
251311
],
252-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
312+
visibility = ["//visibility:public"],
253313
)
254314

255315
# Aggregated targets for Phase 1, Phase 2, Phase 3, Phase 4, and Phase 5
@@ -274,5 +334,5 @@ filegroup(
274334
":inject_appcache",
275335
":exports",
276336
],
277-
visibility = ["//javascript/webdriver-atoms-ts:__subpackages__"],
337+
visibility = ["//visibility:public"],
278338
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Wrapper to make the attribute.get function callable from browser script execution
2+
// This wraps the minified getAttribute function to work with Selenium's .apply() pattern
3+
import { get } from './attribute';
4+
5+
// Return the function directly - esbuild will bundle and return this
6+
export default (element: Element, name: string): string | null => {
7+
return get(element, name);
8+
};
9+
10+
11+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Wrapper for getAttribute that exports to window.__getAttribute__
2+
import { get } from './attribute';
3+
4+
// Export function to window object for browser execution
5+
(globalThis as any).__getAttribute__ = (element: Element, name: string): string | null => {
6+
return get(element, name);
7+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Wrapper for isDisplayed that exports to window.__isDisplayed__
2+
import * as dom from './inject/dom';
3+
4+
(globalThis as any).__isDisplayed__ = (element: any, optWindow?: any): string => {
5+
return dom.isDisplayed(element, optWindow);
6+
};
7+
8+

py/BUILD.bazel

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,21 +114,39 @@ copy_file(
114114
out = "selenium/webdriver/common/windows/selenium-manager.exe",
115115
)
116116

117+
select_file(
118+
name = "attribute-js",
119+
srcs = "//javascript/webdriver-atoms-ts/src:get_attribute_bundle",
120+
subpath = "get_attribute_bundle.js",
121+
)
122+
117123
copy_file(
118124
name = "get-attribute",
119-
src = "//javascript/webdriver/atoms:get-attribute.js",
125+
src = ":attribute-js",
120126
out = "selenium/webdriver/remote/getAttribute.js",
121127
)
122128

129+
select_file(
130+
name = "displayed-js",
131+
srcs = "//javascript/webdriver-atoms-ts/src:is_displayed_bundle",
132+
subpath = "is_displayed_bundle.js",
133+
)
134+
123135
copy_file(
124136
name = "is-displayed",
125-
src = "//javascript/atoms/fragments:is-displayed.js",
137+
src = ":displayed-js",
126138
out = "selenium/webdriver/remote/isDisplayed.js",
127139
)
128140

141+
select_file(
142+
name = "find-element-js",
143+
srcs = "//javascript/webdriver-atoms-ts/src:find_element",
144+
subpath = "find_element.js",
145+
)
146+
129147
copy_file(
130148
name = "find-elements",
131-
src = "//javascript/atoms/fragments:find-elements.js",
149+
src = ":find-element-js",
132150
out = "selenium/webdriver/remote/findElements.js",
133151
)
134152

py/selenium/webdriver/remote/webelement.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def get_attribute(self, name) -> str | None:
211211
if getAttribute_js is None:
212212
_load_js()
213213
attribute_value = self.parent.execute_script(
214-
f"/* getAttribute */return ({getAttribute_js}).apply(null, arguments);", self, name
214+
f"{getAttribute_js}; return __getAttribute__.apply(null, arguments);", self, name
215215
)
216216
return attribute_value
217217

@@ -305,7 +305,7 @@ def is_displayed(self) -> bool:
305305
# Only go into this conditional for browsers that don't use the atom themselves
306306
if isDisplayed_js is None:
307307
_load_js()
308-
return self.parent.execute_script(f"/* isDisplayed */return ({isDisplayed_js}).apply(null, arguments);", self)
308+
return self.parent.execute_script(f"{isDisplayed_js}; return __isDisplayed__.apply(null, arguments);", self)
309309

310310
@property
311311
def location_once_scrolled_into_view(self) -> dict:

0 commit comments

Comments
 (0)