playwright-ruby-client 1.16.0 → 1.18.beta1

Sign up to get free protection for your applications and to get access to all the features.
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: []