playwright-ruby-client 0.5.10 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/docs/api_coverage.md +9 -0
- data/lib/playwright/channel_owners/browser.rb +27 -2
- data/lib/playwright/channel_owners/browser_context.rb +52 -1
- data/lib/playwright/channel_owners/browser_type.rb +8 -1
- data/lib/playwright/channel_owners/element_handle.rb +15 -6
- data/lib/playwright/channel_owners/frame.rb +18 -6
- data/lib/playwright/channel_owners/page.rb +19 -44
- data/lib/playwright/download.rb +3 -2
- data/lib/playwright/events.rb +4 -0
- data/lib/playwright/tracing_impl.rb +31 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/accessibility.rb +8 -7
- data/lib/playwright_api/android.rb +1 -1
- data/lib/playwright_api/browser.rb +43 -0
- data/lib/playwright_api/browser_context.rb +199 -3
- data/lib/playwright_api/browser_type.rb +45 -6
- data/lib/playwright_api/console_message.rb +2 -0
- data/lib/playwright_api/dialog.rb +23 -0
- data/lib/playwright_api/element_handle.rb +124 -20
- data/lib/playwright_api/file_chooser.rb +7 -0
- data/lib/playwright_api/frame.rb +193 -20
- data/lib/playwright_api/js_handle.rb +17 -0
- data/lib/playwright_api/keyboard.rb +48 -0
- data/lib/playwright_api/page.rb +503 -38
- data/lib/playwright_api/playwright.rb +22 -4
- data/lib/playwright_api/request.rb +28 -0
- data/lib/playwright_api/route.rb +22 -2
- data/lib/playwright_api/selectors.rb +25 -0
- data/lib/playwright_api/tracing.rb +99 -0
- data/lib/playwright_api/worker.rb +2 -2
- data/playwright.gemspec +1 -1
- metadata +6 -18
data/lib/playwright/download.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Playwright
|
2
2
|
class Download
|
3
|
-
def initialize(url:, suggested_filename:, artifact:)
|
3
|
+
def initialize(page:, url:, suggested_filename:, artifact:)
|
4
|
+
@page = page
|
4
5
|
@url = url
|
5
6
|
@suggested_filename = suggested_filename
|
6
7
|
@artifact = artifact
|
7
8
|
end
|
8
9
|
|
9
|
-
attr_reader :url, :suggested_filename
|
10
|
+
attr_reader :page, :url, :suggested_filename
|
10
11
|
|
11
12
|
def delete
|
12
13
|
@artifact.delete
|
data/lib/playwright/events.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Playwright
|
2
|
+
define_api_implementation :TracingImpl do
|
3
|
+
def initialize(channel, context)
|
4
|
+
@channel = channel
|
5
|
+
@context = context
|
6
|
+
end
|
7
|
+
|
8
|
+
def start(name: nil, screenshots: nil, snapshots: nil)
|
9
|
+
params = {
|
10
|
+
name: name,
|
11
|
+
screenshots: screenshots,
|
12
|
+
snapshots: snapshots,
|
13
|
+
}.compact
|
14
|
+
@channel.send_message_to_server('tracingStart', params)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Stop tracing.
|
18
|
+
def stop
|
19
|
+
@channel.send_message_to_server('tracingStop')
|
20
|
+
end
|
21
|
+
|
22
|
+
def export(path)
|
23
|
+
resp = @channel.send_message_to_server('tracingExport')
|
24
|
+
artifact = ChannelOwners::Artifact.from(resp)
|
25
|
+
# if self._context._browser:
|
26
|
+
# artifact._is_remote = self._context._browser._is_remote
|
27
|
+
artifact.save_as(path)
|
28
|
+
artifact.delete
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/playwright/version.rb
CHANGED
@@ -44,8 +44,8 @@ module Playwright
|
|
44
44
|
# ```
|
45
45
|
#
|
46
46
|
# ```csharp
|
47
|
-
# var accessibilitySnapshot = await
|
48
|
-
# Console.WriteLine(accessibilitySnapshot);
|
47
|
+
# var accessibilitySnapshot = await page.Accessibility.SnapshotAsync();
|
48
|
+
# Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(accessibilitySnapshot));
|
49
49
|
# ```
|
50
50
|
#
|
51
51
|
# An example of logging the focused node's name:
|
@@ -68,7 +68,7 @@ module Playwright
|
|
68
68
|
# ```
|
69
69
|
#
|
70
70
|
# ```csharp
|
71
|
-
#
|
71
|
+
# static AccessibilitySnapshotResult findFocusedNode(AccessibilitySnapshotResult root)
|
72
72
|
# {
|
73
73
|
# var nodes = new Stack<AccessibilitySnapshotResult>(new[] { root });
|
74
74
|
# while (nodes.Count > 0)
|
@@ -82,12 +82,13 @@ module Playwright
|
|
82
82
|
# }
|
83
83
|
#
|
84
84
|
# return null;
|
85
|
-
# }
|
85
|
+
# }
|
86
86
|
#
|
87
|
-
# var accessibilitySnapshot = await
|
87
|
+
# var accessibilitySnapshot = await page.Accessibility.SnapshotAsync();
|
88
|
+
# Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(accessibilitySnapshot));
|
88
89
|
# var focusedNode = findFocusedNode(accessibilitySnapshot);
|
89
|
-
# if(focusedNode != null)
|
90
|
-
#
|
90
|
+
# if (focusedNode != null)
|
91
|
+
# Console.WriteLine(focusedNode.Name);
|
91
92
|
# ```
|
92
93
|
#
|
93
94
|
# ```java
|
@@ -64,7 +64,7 @@ module Playwright
|
|
64
64
|
# via setting the following environment variable when installing Playwright:
|
65
65
|
#
|
66
66
|
# ```sh js
|
67
|
-
#
|
67
|
+
# PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i -D playwright
|
68
68
|
# ```
|
69
69
|
class Android < PlaywrightApi
|
70
70
|
|
@@ -61,6 +61,24 @@ module Playwright
|
|
61
61
|
# with sync_playwright() as playwright:
|
62
62
|
# run(playwright)
|
63
63
|
# ```
|
64
|
+
#
|
65
|
+
# ```csharp
|
66
|
+
# using Microsoft.Playwright;
|
67
|
+
# using System.Threading.Tasks;
|
68
|
+
#
|
69
|
+
# class BrowserExamples
|
70
|
+
# {
|
71
|
+
# public static async Task Main()
|
72
|
+
# {
|
73
|
+
# using var playwright = await Playwright.CreateAsync();
|
74
|
+
# var firefox = playwright.Firefox;
|
75
|
+
# var browser = await firefox.LaunchAsync(headless: false);
|
76
|
+
# var page = await browser.NewPageAsync();
|
77
|
+
# await page.GotoAsync("https://www.bing.com");
|
78
|
+
# await browser.CloseAsync();
|
79
|
+
# }
|
80
|
+
# }
|
81
|
+
# ```
|
64
82
|
class Browser < PlaywrightApi
|
65
83
|
|
66
84
|
# In case this browser is obtained using [`method: BrowserType.launch`], closes the browser and all of its pages (if any
|
@@ -105,6 +123,14 @@ module Playwright
|
|
105
123
|
# context = browser.new_context()
|
106
124
|
# print(len(browser.contexts())) # prints `1`
|
107
125
|
# ```
|
126
|
+
#
|
127
|
+
# ```csharp
|
128
|
+
# using var playwright = await Playwright.CreateAsync();
|
129
|
+
# var browser = await playwright.Webkit.LaunchAsync();
|
130
|
+
# System.Console.WriteLine(browser.Contexts.Count); // prints "0"
|
131
|
+
# var context = await browser.NewContextAsync();
|
132
|
+
# System.Console.WriteLine(browser.Contexts.Count); // prints "1"
|
133
|
+
# ```
|
108
134
|
def contexts
|
109
135
|
wrap_impl(@impl.contexts)
|
110
136
|
end
|
@@ -161,6 +187,16 @@ module Playwright
|
|
161
187
|
# page = context.new_page()
|
162
188
|
# page.goto("https://example.com")
|
163
189
|
# ```
|
190
|
+
#
|
191
|
+
# ```csharp
|
192
|
+
# using var playwright = await Playwright.CreateAsync();
|
193
|
+
# var browser = await playwright.Firefox.LaunchAsync();
|
194
|
+
# // Create a new incognito browser context.
|
195
|
+
# var context = await browser.NewContextAsync();
|
196
|
+
# // Create a new page in a pristine context.
|
197
|
+
# var page = await context.NewPageAsync(); ;
|
198
|
+
# await page.GotoAsync("https://www.bing.com");
|
199
|
+
# ```
|
164
200
|
def new_context(
|
165
201
|
acceptDownloads: nil,
|
166
202
|
bypassCSP: nil,
|
@@ -237,6 +273,13 @@ module Playwright
|
|
237
273
|
# await browser.stopTracing();
|
238
274
|
# ```
|
239
275
|
#
|
276
|
+
# ```java
|
277
|
+
# browser.startTracing(page, new Browser.StartTracingOptions()
|
278
|
+
# .setPath(Paths.get("trace.json")));
|
279
|
+
# page.goto('https://www.google.com');
|
280
|
+
# browser.stopTracing();
|
281
|
+
# ```
|
282
|
+
#
|
240
283
|
# ```python async
|
241
284
|
# await browser.start_tracing(page, path="trace.json")
|
242
285
|
# await page.goto("https://www.google.com")
|
@@ -26,7 +26,7 @@ module Playwright
|
|
26
26
|
# // Create a new page inside context.
|
27
27
|
# Page page = context.newPage();
|
28
28
|
# page.navigate("https://example.com");
|
29
|
-
# // Dispose context once it
|
29
|
+
# // Dispose context once it is no longer needed.
|
30
30
|
# context.close();
|
31
31
|
# ```
|
32
32
|
#
|
@@ -36,7 +36,7 @@ module Playwright
|
|
36
36
|
# # create a new page inside context.
|
37
37
|
# page = await context.new_page()
|
38
38
|
# await page.goto("https://example.com")
|
39
|
-
# # dispose context once it
|
39
|
+
# # dispose context once it is no longer needed.
|
40
40
|
# await context.close()
|
41
41
|
# ```
|
42
42
|
#
|
@@ -46,11 +46,27 @@ module Playwright
|
|
46
46
|
# # create a new page inside context.
|
47
47
|
# page = context.new_page()
|
48
48
|
# page.goto("https://example.com")
|
49
|
-
# # dispose context once it
|
49
|
+
# # dispose context once it is no longer needed.
|
50
50
|
# context.close()
|
51
51
|
# ```
|
52
|
+
#
|
53
|
+
# ```csharp
|
54
|
+
# using var playwright = await Playwright.CreateAsync();
|
55
|
+
# var browser = await playwright.Firefox.LaunchAsync(headless: false);
|
56
|
+
# // Create a new incognito browser context
|
57
|
+
# var context = await browser.NewContextAsync();
|
58
|
+
# // Create a new page inside context.
|
59
|
+
# var page = await context.NewPageAsync();
|
60
|
+
# await page.GotoAsync("https://bing.com");
|
61
|
+
# // Dispose context once it is no longer needed.
|
62
|
+
# await context.CloseAsync();
|
63
|
+
# ```
|
52
64
|
class BrowserContext < PlaywrightApi
|
53
65
|
|
66
|
+
def tracing # property
|
67
|
+
wrap_impl(@impl.tracing)
|
68
|
+
end
|
69
|
+
|
54
70
|
# Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be
|
55
71
|
# obtained via [`method: BrowserContext.cookies`].
|
56
72
|
#
|
@@ -70,6 +86,10 @@ module Playwright
|
|
70
86
|
# ```python sync
|
71
87
|
# browser_context.add_cookies([cookie_object1, cookie_object2])
|
72
88
|
# ```
|
89
|
+
#
|
90
|
+
# ```csharp
|
91
|
+
# await context.AddCookiesAsync(new[] { cookie1, cookie2 });
|
92
|
+
# ```
|
73
93
|
def add_cookies(cookies)
|
74
94
|
wrap_impl(@impl.add_cookies(unwrap_impl(cookies)))
|
75
95
|
end
|
@@ -113,6 +133,10 @@ module Playwright
|
|
113
133
|
# browser_context.add_init_script(path="preload.js")
|
114
134
|
# ```
|
115
135
|
#
|
136
|
+
# ```csharp
|
137
|
+
# await context.AddInitScriptAsync(scriptPath: "preload.js");
|
138
|
+
# ```
|
139
|
+
#
|
116
140
|
# > NOTE: The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
|
117
141
|
# [`method: Page.addInitScript`] is not defined.
|
118
142
|
def add_init_script(path: nil, script: nil)
|
@@ -166,6 +190,15 @@ module Playwright
|
|
166
190
|
# # do stuff ..
|
167
191
|
# context.clear_permissions()
|
168
192
|
# ```
|
193
|
+
#
|
194
|
+
# ```csharp
|
195
|
+
# var context = await browser.NewContextAsync();
|
196
|
+
# await context.GrantPermissionsAsync(new[] { "clipboard-read" });
|
197
|
+
# // Alternatively, you can use the helper class ContextPermissions
|
198
|
+
# // to specify the permissions...
|
199
|
+
# // do stuff ...
|
200
|
+
# await context.ClearPermissionsAsync();
|
201
|
+
# ```
|
169
202
|
def clear_permissions
|
170
203
|
wrap_impl(@impl.clear_permissions)
|
171
204
|
end
|
@@ -291,6 +324,32 @@ module Playwright
|
|
291
324
|
# run(playwright)
|
292
325
|
# ```
|
293
326
|
#
|
327
|
+
# ```csharp
|
328
|
+
# using Microsoft.Playwright;
|
329
|
+
# using System.Threading.Tasks;
|
330
|
+
#
|
331
|
+
# class Program
|
332
|
+
# {
|
333
|
+
# public static async Task Main()
|
334
|
+
# {
|
335
|
+
# using var playwright = await Playwright.CreateAsync();
|
336
|
+
# var browser = await playwright.Webkit.LaunchAsync(headless: false);
|
337
|
+
# var context = await browser.NewContextAsync();
|
338
|
+
#
|
339
|
+
# await context.ExposeBindingAsync("pageURL", source => source.Page.Url);
|
340
|
+
# var page = await context.NewPageAsync();
|
341
|
+
# await page.SetContentAsync("<script>\n" +
|
342
|
+
# " async function onClick() {\n" +
|
343
|
+
# " document.querySelector('div').textContent = await window.pageURL();\n" +
|
344
|
+
# " }\n" +
|
345
|
+
# "</script>\n" +
|
346
|
+
# "<button onclick=\"onClick()\">Click me</button>\n" +
|
347
|
+
# "<div></div>");
|
348
|
+
# await page.ClickAsync("button");
|
349
|
+
# }
|
350
|
+
# }
|
351
|
+
# ```
|
352
|
+
#
|
294
353
|
# An example of passing an element handle:
|
295
354
|
#
|
296
355
|
#
|
@@ -348,6 +407,26 @@ module Playwright
|
|
348
407
|
# <div>Or click me</div>
|
349
408
|
# """)
|
350
409
|
# ```
|
410
|
+
#
|
411
|
+
# ```csharp
|
412
|
+
# var result = new TaskCompletionSource<string>();
|
413
|
+
# var page = await Context.NewPageAsync();
|
414
|
+
# await Context.ExposeBindingAsync("clicked", async (BindingSource _, IJSHandle t) =>
|
415
|
+
# {
|
416
|
+
# return result.TrySetResult(await t.AsElement.TextContentAsync());
|
417
|
+
# });
|
418
|
+
#
|
419
|
+
# await page.SetContentAsync("<script>\n" +
|
420
|
+
# " document.addEventListener('click', event => window.clicked(event.target));\n" +
|
421
|
+
# "</script>\n" +
|
422
|
+
# "<div>Click me</div>\n" +
|
423
|
+
# "<div>Or click me</div>\n");
|
424
|
+
#
|
425
|
+
# await page.ClickAsync("div");
|
426
|
+
# // Note: it makes sense to await the result here, because otherwise, the context
|
427
|
+
# // gets closed and the binding function will throw an exception.
|
428
|
+
# Assert.Equal("Click me", await result.Task);
|
429
|
+
# ```
|
351
430
|
def expose_binding(name, callback, handle: nil)
|
352
431
|
wrap_impl(@impl.expose_binding(unwrap_impl(name), unwrap_impl(callback), handle: unwrap_impl(handle)))
|
353
432
|
end
|
@@ -487,6 +566,43 @@ module Playwright
|
|
487
566
|
# with sync_playwright() as playwright:
|
488
567
|
# run(playwright)
|
489
568
|
# ```
|
569
|
+
#
|
570
|
+
# ```csharp
|
571
|
+
# using Microsoft.Playwright;
|
572
|
+
# using System;
|
573
|
+
# using System.Security.Cryptography;
|
574
|
+
# using System.Threading.Tasks;
|
575
|
+
#
|
576
|
+
# class BrowserContextExamples
|
577
|
+
# {
|
578
|
+
# public static async Task AddMd5FunctionToAllPagesInContext()
|
579
|
+
# {
|
580
|
+
# using var playwright = await Playwright.CreateAsync();
|
581
|
+
# var browser = await playwright.Webkit.LaunchAsync(headless: false);
|
582
|
+
# var context = await browser.NewContextAsync();
|
583
|
+
#
|
584
|
+
# // NOTE: md5 is inherently insecure, and we strongly discourage using
|
585
|
+
# // this in production in any shape or form
|
586
|
+
# await context.ExposeFunctionAsync("sha1", (string input) =>
|
587
|
+
# {
|
588
|
+
# return Convert.ToBase64String(
|
589
|
+
# MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(input)));
|
590
|
+
# });
|
591
|
+
#
|
592
|
+
# var page = await context.NewPageAsync();
|
593
|
+
# await page.SetContentAsync("<script>\n" +
|
594
|
+
# " async function onClick() {\n" +
|
595
|
+
# " document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');\n" +
|
596
|
+
# " }\n" +
|
597
|
+
# "</script>\n" +
|
598
|
+
# "<button onclick=\"onClick()\">Click me</button>\n" +
|
599
|
+
# "<div></div>");
|
600
|
+
#
|
601
|
+
# await page.ClickAsync("button");
|
602
|
+
# Console.WriteLine(await page.TextContentAsync("div"));
|
603
|
+
# }
|
604
|
+
# }
|
605
|
+
# ```
|
490
606
|
def expose_function(name, callback)
|
491
607
|
wrap_impl(@impl.expose_function(unwrap_impl(name), unwrap_impl(callback)))
|
492
608
|
end
|
@@ -552,6 +668,14 @@ module Playwright
|
|
552
668
|
# browser.close()
|
553
669
|
# ```
|
554
670
|
#
|
671
|
+
# ```csharp
|
672
|
+
# var context = await browser.NewContextAsync();
|
673
|
+
# var page = await context.NewPageAsync();
|
674
|
+
# await context.RouteAsync("**/*.{png,jpg,jpeg}", r => r.AbortAsync());
|
675
|
+
# await page.GotoAsync("https://theverge.com");
|
676
|
+
# await browser.CloseAsync();
|
677
|
+
# ```
|
678
|
+
#
|
555
679
|
# or the same snippet using a regex pattern instead:
|
556
680
|
#
|
557
681
|
#
|
@@ -590,6 +714,64 @@ module Playwright
|
|
590
714
|
# browser.close()
|
591
715
|
# ```
|
592
716
|
#
|
717
|
+
# ```csharp
|
718
|
+
# var context = await browser.NewContextAsync();
|
719
|
+
# var page = await context.NewPageAsync();
|
720
|
+
# await context.RouteAsync(new Regex("(\\.png$)|(\\.jpg$)"), r => r.AbortAsync());
|
721
|
+
# await page.GotoAsync("https://theverge.com");
|
722
|
+
# await browser.CloseAsync();
|
723
|
+
# ```
|
724
|
+
#
|
725
|
+
# It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
|
726
|
+
# post data, and leaving all other requests as is:
|
727
|
+
#
|
728
|
+
#
|
729
|
+
# ```js
|
730
|
+
# await context.route('/api/**', route => {
|
731
|
+
# if (route.request().postData().includes('my-string'))
|
732
|
+
# route.fulfill({ body: 'mocked-data' });
|
733
|
+
# else
|
734
|
+
# route.continue();
|
735
|
+
# });
|
736
|
+
# ```
|
737
|
+
#
|
738
|
+
# ```java
|
739
|
+
# context.route("/api/**", route -> {
|
740
|
+
# if (route.request().postData().contains("my-string"))
|
741
|
+
# route.fulfill(new Route.FulfillOptions().setBody("mocked-data"));
|
742
|
+
# else
|
743
|
+
# route.resume();
|
744
|
+
# });
|
745
|
+
# ```
|
746
|
+
#
|
747
|
+
# ```python async
|
748
|
+
# def handle_route(route):
|
749
|
+
# if ("my-string" in route.request.post_data)
|
750
|
+
# route.fulfill(body="mocked-data")
|
751
|
+
# else
|
752
|
+
# route.continue_()
|
753
|
+
# await context.route("/api/**", handle_route)
|
754
|
+
# ```
|
755
|
+
#
|
756
|
+
# ```python sync
|
757
|
+
# def handle_route(route):
|
758
|
+
# if ("my-string" in route.request.post_data)
|
759
|
+
# route.fulfill(body="mocked-data")
|
760
|
+
# else
|
761
|
+
# route.continue_()
|
762
|
+
# context.route("/api/**", handle_route)
|
763
|
+
# ```
|
764
|
+
#
|
765
|
+
# ```csharp
|
766
|
+
# await page.RouteAsync("/api/**", async r =>
|
767
|
+
# {
|
768
|
+
# if (r.Request.PostData.Contains("my-string"))
|
769
|
+
# await r.FulfillAsync(body: "mocked-data");
|
770
|
+
# else
|
771
|
+
# await r.ContinueAsync();
|
772
|
+
# });
|
773
|
+
# ```
|
774
|
+
#
|
593
775
|
# Page routes (set up with [`method: Page.route`]) take precedence over browser context routes when request matches both
|
594
776
|
# handlers.
|
595
777
|
#
|
@@ -660,6 +842,14 @@ module Playwright
|
|
660
842
|
# browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
|
661
843
|
# ```
|
662
844
|
#
|
845
|
+
# ```csharp
|
846
|
+
# await context.SetGeolocationAsync(new Geolocation()
|
847
|
+
# {
|
848
|
+
# Latitude = 59.95f,
|
849
|
+
# Longitude = 30.31667f
|
850
|
+
# });
|
851
|
+
# ```
|
852
|
+
#
|
663
853
|
# > NOTE: Consider using [`method: BrowserContext.grantPermissions`] to grant permissions for the browser context pages to
|
664
854
|
# read its geolocation.
|
665
855
|
def set_geolocation(geolocation)
|
@@ -709,6 +899,12 @@ module Playwright
|
|
709
899
|
# page.click("button")
|
710
900
|
# page = event_info.value
|
711
901
|
# ```
|
902
|
+
#
|
903
|
+
# ```csharp
|
904
|
+
# var waitForPageEvent = context.WaitForPageAsync();
|
905
|
+
# await page.ClickAsync("button");
|
906
|
+
# var page = await waitForPageEvent;
|
907
|
+
# ```
|
712
908
|
def expect_event(event, predicate: nil, timeout: nil, &block)
|
713
909
|
wrap_impl(@impl.expect_event(unwrap_impl(event), predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
714
910
|
end
|