playwright-ruby-client 1.16.0 → 1.18.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +49 -0
  3. data/documentation/docs/api/download.md +1 -3
  4. data/documentation/docs/api/element_handle.md +2 -3
  5. data/documentation/docs/api/frame.md +31 -1
  6. data/documentation/docs/api/frame_locator.md +79 -0
  7. data/documentation/docs/api/locator.md +36 -49
  8. data/documentation/docs/api/page.md +34 -4
  9. data/documentation/docs/api/request.md +3 -3
  10. data/documentation/docs/api/selectors.md +1 -1
  11. data/documentation/docs/api/tracing.md +2 -2
  12. data/documentation/docs/include/api_coverage.md +18 -0
  13. data/lib/playwright/channel.rb +1 -1
  14. data/lib/playwright/channel_owners/artifact.rb +1 -6
  15. data/lib/playwright/channel_owners/browser.rb +6 -8
  16. data/lib/playwright/channel_owners/browser_context.rb +5 -3
  17. data/lib/playwright/channel_owners/browser_type.rb +0 -1
  18. data/lib/playwright/channel_owners/fetch_request.rb +2 -0
  19. data/lib/playwright/channel_owners/frame.rb +10 -6
  20. data/lib/playwright/channel_owners/local_utils.rb +14 -0
  21. data/lib/playwright/channel_owners/page.rb +13 -10
  22. data/lib/playwright/connection.rb +9 -0
  23. data/lib/playwright/frame_locator_impl.rb +50 -0
  24. data/lib/playwright/locator_impl.rb +75 -8
  25. data/lib/playwright/tracing_impl.rb +25 -14
  26. data/lib/playwright/version.rb +2 -2
  27. data/lib/playwright/video.rb +3 -0
  28. data/lib/playwright.rb +2 -1
  29. data/lib/playwright_api/android_device.rb +4 -4
  30. data/lib/playwright_api/api_request_context.rb +50 -0
  31. data/lib/playwright_api/browser_context.rb +11 -6
  32. data/lib/playwright_api/download.rb +0 -4
  33. data/lib/playwright_api/element_handle.rb +2 -3
  34. data/lib/playwright_api/frame.rb +28 -3
  35. data/lib/playwright_api/frame_locator.rb +60 -0
  36. data/lib/playwright_api/local_utils.rb +9 -0
  37. data/lib/playwright_api/locator.rb +28 -48
  38. data/lib/playwright_api/page.rb +36 -6
  39. data/lib/playwright_api/playwright.rb +9 -4
  40. data/lib/playwright_api/selectors.rb +2 -2
  41. data/lib/playwright_api/tracing.rb +4 -4
  42. data/playwright.gemspec +1 -1
  43. metadata +13 -8
@@ -0,0 +1,60 @@
1
+ module Playwright
2
+ # FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe`
3
+ # and locate elements in that iframe. FrameLocator can be created with either [`method: Page.frameLocator`] or
4
+ # [`method: Locator.frameLocator`] method.
5
+ #
6
+ # ```python sync
7
+ # locator = page.frame_locator("my-frame").locator("text=Submit")
8
+ # locator.click()
9
+ # ```
10
+ #
11
+ # **Strictness**
12
+ #
13
+ # Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
14
+ # given selector.
15
+ #
16
+ # ```python sync
17
+ # # Throws if there are several frames in DOM:
18
+ # page.frame_locator('.result-frame').locator('button').click()
19
+ #
20
+ # # Works because we explicitly tell locator to pick the first frame:
21
+ # page.frame_locator('.result-frame').first.locator('button').click()
22
+ # ```
23
+ #
24
+ # **Converting Locator to FrameLocator**
25
+ #
26
+ # If you have a `Locator` object pointing to an `iframe` it can be converted to `FrameLocator` using
27
+ # [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) CSS selector:
28
+ #
29
+ # ```python sync
30
+ # frameLocator = locator.frame_locator(":scope");
31
+ # ```
32
+ class FrameLocator < PlaywrightApi
33
+
34
+ # Returns locator to the first matching frame.
35
+ def first
36
+ wrap_impl(@impl.first)
37
+ end
38
+
39
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
40
+ # that iframe.
41
+ def frame_locator(selector)
42
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
43
+ end
44
+
45
+ # Returns locator to the last matching frame.
46
+ def last
47
+ wrap_impl(@impl.last)
48
+ end
49
+
50
+ # The method finds an element matching the specified selector in the FrameLocator's subtree.
51
+ def locator(selector, hasText: nil)
52
+ wrap_impl(@impl.locator(unwrap_impl(selector), hasText: unwrap_impl(hasText)))
53
+ end
54
+
55
+ # Returns locator to the n-th matching frame.
56
+ def nth(index)
57
+ wrap_impl(@impl.nth(unwrap_impl(index)))
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ module Playwright
2
+ class LocalUtils < PlaywrightApi
3
+
4
+ # @nodoc
5
+ def zip(zip_file, name_value_array)
6
+ wrap_impl(@impl.zip(unwrap_impl(zip_file), unwrap_impl(name_value_array)))
7
+ end
8
+ end
9
+ end
@@ -1,49 +1,8 @@
1
1
  module Playwright
2
- # Locator represents a view to the element(s) on the page. It captures the logic sufficient to retrieve the element at any
3
- # given moment. Locator can be created with the [`method: Page.locator`] method.
2
+ # Locators are the central piece of Playwright's auto-waiting and retry-ability. In a nutshell, locators represent a way
3
+ # to find element(s) on the page at any moment. Locator can be created with the [`method: Page.locator`] method.
4
4
  #
5
- # ```python sync
6
- # locator = page.locator("text=Submit")
7
- # locator.click()
8
- # ```
9
- #
10
- # The difference between the Locator and `ElementHandle` is that the latter points to a particular element, while Locator
11
- # captures the logic of how to retrieve that element.
12
- #
13
- # In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
14
- # React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
15
- # unexpected behaviors.
16
- #
17
- # ```python sync
18
- # handle = page.query_selector("text=Submit")
19
- # handle.hover()
20
- # handle.click()
21
- # ```
22
- #
23
- # With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
24
- # in the snippet below, underlying DOM element is going to be located twice.
25
- #
26
- # ```python sync
27
- # locator = page.locator("text=Submit")
28
- # locator.hover()
29
- # locator.click()
30
- # ```
31
- #
32
- # **Strictness**
33
- #
34
- # Locators are strict. This means that all operations on locators that imply some target DOM element will throw if more
35
- # than one element matches given selector.
36
- #
37
- # ```python sync
38
- # # Throws if there are several buttons in DOM:
39
- # page.locator('button').click()
40
- #
41
- # # Works because we explicitly tell locator to pick the first element:
42
- # page.locator('button').first.click()
43
- #
44
- # # Works because count knows what to do with multiple matches:
45
- # page.locator('button').count()
46
- # ```
5
+ # [Learn more about locators](./locators.md).
47
6
  class Locator < PlaywrightApi
48
7
 
49
8
  # Returns an array of `node.innerText` values for all matching nodes.
@@ -183,6 +142,17 @@ module Playwright
183
142
  wrap_impl(@impl.dispatch_event(unwrap_impl(type), eventInit: unwrap_impl(eventInit), timeout: unwrap_impl(timeout)))
184
143
  end
185
144
 
145
+ def drag_to(
146
+ target,
147
+ force: nil,
148
+ noWaitAfter: nil,
149
+ sourcePosition: nil,
150
+ targetPosition: nil,
151
+ timeout: nil,
152
+ trial: nil)
153
+ wrap_impl(@impl.drag_to(unwrap_impl(target), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), sourcePosition: unwrap_impl(sourcePosition), targetPosition: unwrap_impl(targetPosition), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
154
+ end
155
+
186
156
  # Resolves given locator to the first matching DOM element. If no elements matching the query are visible, waits for them
187
157
  # up to a given timeout. If multiple elements match the selector, throws.
188
158
  def element_handle(timeout: nil)
@@ -264,6 +234,17 @@ module Playwright
264
234
  wrap_impl(@impl.focus(timeout: unwrap_impl(timeout)))
265
235
  end
266
236
 
237
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
238
+ # that iframe:
239
+ #
240
+ # ```python sync
241
+ # locator = page.frame_locator("text=Submit").locator("text=Submit")
242
+ # locator.click()
243
+ # ```
244
+ def frame_locator(selector)
245
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
246
+ end
247
+
267
248
  # Returns element attribute value.
268
249
  def get_attribute(name, timeout: nil)
269
250
  wrap_impl(@impl.get_attribute(unwrap_impl(name), timeout: unwrap_impl(timeout)))
@@ -338,10 +319,9 @@ module Playwright
338
319
  wrap_impl(@impl.last)
339
320
  end
340
321
 
341
- # The method finds an element matching the specified selector in the `Locator`'s subtree. See
342
- # [Working with selectors](./selectors.md) for more details.
343
- def locator(selector)
344
- wrap_impl(@impl.locator(unwrap_impl(selector)))
322
+ # The method finds an element matching the specified selector in the `Locator`'s subtree.
323
+ def locator(selector, hasText: nil)
324
+ wrap_impl(@impl.locator(unwrap_impl(selector), hasText: unwrap_impl(hasText)))
345
325
  end
346
326
 
347
327
  # Returns locator to the n-th matching element.
@@ -56,6 +56,11 @@ module Playwright
56
56
  wrap_impl(@impl.mouse)
57
57
  end
58
58
 
59
+ # API testing helper associated with this page. Requests made with this API will use page cookies.
60
+ def request # property
61
+ raise NotImplementedError.new('request is not implemented yet.')
62
+ end
63
+
59
64
  def touchscreen # property
60
65
  wrap_impl(@impl.touchscreen)
61
66
  end
@@ -288,6 +293,9 @@ module Playwright
288
293
  wrap_impl(@impl.emulate_media(colorScheme: unwrap_impl(colorScheme), forcedColors: unwrap_impl(forcedColors), media: unwrap_impl(media), reducedMotion: unwrap_impl(reducedMotion)))
289
294
  end
290
295
 
296
+ # > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
297
+ # tests. Use [`method: Locator.evaluate`], other `Locator` helper methods or web-first assertions instead.
298
+ #
291
299
  # The method finds an element matching the specified selector within the page and passes it as a first argument to
292
300
  # `expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`.
293
301
  #
@@ -307,6 +315,9 @@ module Playwright
307
315
  wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg), strict: unwrap_impl(strict)))
308
316
  end
309
317
 
318
+ # > NOTE: In most cases, [`method: Locator.evaluateAll`], other `Locator` helper methods and web-first assertions do a
319
+ # better job.
320
+ #
310
321
  # The method finds all elements matching the specified selector within the page and passes an array of matched elements as
311
322
  # a first argument to `expression`. Returns the result of `expression` invocation.
312
323
  #
@@ -349,7 +360,7 @@ module Playwright
349
360
  # `ElementHandle` instances can be passed as an argument to the [`method: Page.evaluate`]:
350
361
  #
351
362
  # ```python sync
352
- # body_handle = page.query_selector("body")
363
+ # body_handle = page.evaluate("document.body")
353
364
  # html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
354
365
  # body_handle.dispose()
355
366
  # ```
@@ -533,6 +544,18 @@ module Playwright
533
544
  wrap_impl(@impl.frame(name: unwrap_impl(name), url: unwrap_impl(url)))
534
545
  end
535
546
 
547
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
548
+ # that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
549
+ # id="my-frame">`:
550
+ #
551
+ # ```python sync
552
+ # locator = page.frame_locator("#my-iframe").locator("text=Submit")
553
+ # locator.click()
554
+ # ```
555
+ def frame_locator(selector)
556
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
557
+ end
558
+
536
559
  # An array of all frames attached to the page.
537
560
  def frames
538
561
  wrap_impl(@impl.frames)
@@ -663,8 +686,8 @@ module Playwright
663
686
  # different DOM elements. That would happen if the DOM structure between those actions has changed.
664
687
  #
665
688
  # Shortcut for main frame's [`method: Frame.locator`].
666
- def locator(selector)
667
- wrap_impl(@impl.locator(unwrap_impl(selector)))
689
+ def locator(selector, hasText: nil)
690
+ wrap_impl(@impl.locator(unwrap_impl(selector), hasText: unwrap_impl(hasText)))
668
691
  end
669
692
 
670
693
  # The page's main frame. Page is guaranteed to have a main frame which persists during navigations.
@@ -791,14 +814,18 @@ module Playwright
791
814
  wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
792
815
  end
793
816
 
817
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
818
+ #
794
819
  # The method finds an element matching the specified selector within the page. If no elements match the selector, the
795
- # return value resolves to `null`. To wait for an element on the page, use [`method: Page.waitForSelector`].
820
+ # return value resolves to `null`. To wait for an element on the page, use [`method: Locator.waitFor`].
796
821
  #
797
822
  # Shortcut for main frame's [`method: Frame.querySelector`].
798
823
  def query_selector(selector, strict: nil)
799
824
  wrap_impl(@impl.query_selector(unwrap_impl(selector), strict: unwrap_impl(strict)))
800
825
  end
801
826
 
827
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
828
+ #
802
829
  # The method finds all elements matching the specified selector within the page. If no elements match the selector, the
803
830
  # return value resolves to `[]`.
804
831
  #
@@ -807,8 +834,8 @@ module Playwright
807
834
  wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
808
835
  end
809
836
 
810
- # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
811
- # last redirect.
837
+ # This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main
838
+ # resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
812
839
  def reload(timeout: nil, waitUntil: nil)
813
840
  wrap_impl(@impl.reload(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
814
841
  end
@@ -1267,6 +1294,9 @@ module Playwright
1267
1294
  # Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
1268
1295
  # `detached`.
1269
1296
  #
1297
+ # > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and
1298
+ # web-first assertions make the code wait-for-selector-free.
1299
+ #
1270
1300
  # Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
1271
1301
  # the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
1272
1302
  # selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@@ -50,6 +50,11 @@ module Playwright
50
50
  wrap_impl(@impl.firefox)
51
51
  end
52
52
 
53
+ # Exposes API that can be used for the Web API testing.
54
+ def request # property
55
+ raise NotImplementedError.new('request is not implemented yet.')
56
+ end
57
+
53
58
  # Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md) for more
54
59
  # information.
55
60
  def selectors # property
@@ -82,13 +87,13 @@ module Playwright
82
87
  end
83
88
 
84
89
  # @nodoc
85
- def electron
86
- wrap_impl(@impl.electron)
90
+ def android
91
+ wrap_impl(@impl.android)
87
92
  end
88
93
 
89
94
  # @nodoc
90
- def android
91
- wrap_impl(@impl.android)
95
+ def electron
96
+ wrap_impl(@impl.electron)
92
97
  end
93
98
 
94
99
  # -- inherited from EventEmitter --
@@ -28,11 +28,11 @@ module Playwright
28
28
  # page.set_content('<div><button>Click me</button></div>')
29
29
  #
30
30
  # # Use the selector prefixed with its name.
31
- # button = page.query_selector('tag=button')
31
+ # button = page.locator('tag=button')
32
32
  # # Combine it with other selector engines.
33
33
  # page.click('tag=div >> text="Click me"')
34
34
  # # Can use it in any methods supporting selectors.
35
- # button_count = page.eval_on_selector_all('tag=button', 'buttons => buttons.length')
35
+ # button_count = page.locator('tag=button').count()
36
36
  # print(button_count)
37
37
  # browser.close()
38
38
  #
@@ -22,8 +22,8 @@ module Playwright
22
22
  # page.goto("https://playwright.dev")
23
23
  # context.tracing.stop(path = "trace.zip")
24
24
  # ```
25
- def start(name: nil, screenshots: nil, snapshots: nil)
26
- wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots)))
25
+ def start(name: nil, screenshots: nil, snapshots: nil, title: nil)
26
+ wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots), title: unwrap_impl(title)))
27
27
  end
28
28
 
29
29
  # Start a new trace chunk. If you'd like to record multiple traces on the same `BrowserContext`, use
@@ -45,8 +45,8 @@ module Playwright
45
45
  # # Save a second trace file with different actions.
46
46
  # context.tracing.stop_chunk(path = "trace2.zip")
47
47
  # ```
48
- def start_chunk
49
- wrap_impl(@impl.start_chunk)
48
+ def start_chunk(title: nil)
49
+ wrap_impl(@impl.start_chunk(title: unwrap_impl(title)))
50
50
  end
51
51
 
52
52
  # Stop tracing.
data/playwright.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.required_ruby_version = '>= 2.4'
28
28
  spec.add_dependency 'concurrent-ruby', '>= 1.1.6'
29
29
  spec.add_dependency 'mime-types', '>= 3.0'
30
- spec.add_development_dependency 'bundler', '~> 2.2.3'
30
+ spec.add_development_dependency 'bundler', '~> 2.3.0'
31
31
  spec.add_development_dependency 'chunky_png'
32
32
  spec.add_development_dependency 'dry-inflector'
33
33
  spec.add_development_dependency 'faye-websocket'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playwright-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.18.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-24 00:00:00.000000000 Z
11
+ date: 2022-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.2.3
47
+ version: 2.3.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.2.3
54
+ version: 2.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: chunky_png
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +227,7 @@ files:
227
227
  - documentation/docs/api/experimental/android_web_view.md
228
228
  - documentation/docs/api/file_chooser.md
229
229
  - documentation/docs/api/frame.md
230
+ - documentation/docs/api/frame_locator.md
230
231
  - documentation/docs/api/js_handle.md
231
232
  - documentation/docs/api/keyboard.md
232
233
  - documentation/docs/api/locator.md
@@ -292,6 +293,7 @@ files:
292
293
  - lib/playwright/channel_owners/fetch_request.rb
293
294
  - lib/playwright/channel_owners/frame.rb
294
295
  - lib/playwright/channel_owners/js_handle.rb
296
+ - lib/playwright/channel_owners/local_utils.rb
295
297
  - lib/playwright/channel_owners/page.rb
296
298
  - lib/playwright/channel_owners/playwright.rb
297
299
  - lib/playwright/channel_owners/request.rb
@@ -308,6 +310,7 @@ files:
308
310
  - lib/playwright/event_emitter_proxy.rb
309
311
  - lib/playwright/events.rb
310
312
  - lib/playwright/file_chooser_impl.rb
313
+ - lib/playwright/frame_locator_impl.rb
311
314
  - lib/playwright/http_headers.rb
312
315
  - lib/playwright/input_files.rb
313
316
  - lib/playwright/javascript.rb
@@ -349,8 +352,10 @@ files:
349
352
  - lib/playwright_api/element_handle.rb
350
353
  - lib/playwright_api/file_chooser.rb
351
354
  - lib/playwright_api/frame.rb
355
+ - lib/playwright_api/frame_locator.rb
352
356
  - lib/playwright_api/js_handle.rb
353
357
  - lib/playwright_api/keyboard.rb
358
+ - lib/playwright_api/local_utils.rb
354
359
  - lib/playwright_api/locator.rb
355
360
  - lib/playwright_api/mouse.rb
356
361
  - lib/playwright_api/page.rb
@@ -379,12 +384,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
379
384
  version: '2.4'
380
385
  required_rubygems_version: !ruby/object:Gem::Requirement
381
386
  requirements:
382
- - - ">="
387
+ - - ">"
383
388
  - !ruby/object:Gem::Version
384
- version: '0'
389
+ version: 1.3.1
385
390
  requirements: []
386
- rubygems_version: 3.2.22
391
+ rubygems_version: 3.3.3
387
392
  signing_key:
388
393
  specification_version: 4
389
- summary: The Ruby binding of playwright driver 1.16.0
394
+ summary: The Ruby binding of playwright driver 1.18.0
390
395
  test_files: []