Skip to content

Commit

Permalink
Merge pull request #304 from YusukeIwaki/driver/1.47.1
Browse files Browse the repository at this point in the history
Update Playwright driver to 1.47.1
  • Loading branch information
YusukeIwaki authored Sep 14, 2024
2 parents 6baa4f5 + 592f1ad commit 26b2ae1
Show file tree
Hide file tree
Showing 12 changed files with 1,735 additions and 387 deletions.
2 changes: 1 addition & 1 deletion development/CLI_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.46.1
1.47.1
2,010 changes: 1,652 additions & 358 deletions development/api.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion documentation/docs/api/api_response.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def headers_array
```


An array with all the request HTTP headers associated with this response. Header names are not lower-cased.
An array with all the response HTTP headers associated with this response. Header names are not lower-cased.
Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times.

## json
Expand Down
1 change: 0 additions & 1 deletion documentation/docs/api/browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ sidebar_position: 10

# Browser

- extends: [EventEmitter]

A Browser is created via [BrowserType#launch](./browser_type#launch). An example of using a [Browser](./browser) to create a [Page](./page):

Expand Down
3 changes: 1 addition & 2 deletions documentation/docs/api/browser_context.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ sidebar_position: 10

# BrowserContext

- extends: [EventEmitter]

BrowserContexts provide a way to operate multiple independent browser sessions.

If a page opens another page, e.g. with a `window.open` call, the popup will belong to the parent page's browser
context.

Playwright allows creating "incognito" browser contexts with [Browser#new_context](./browser#new_context) method. "Incognito" browser
Playwright allows creating isolated non-persistent browser contexts with [Browser#new_context](./browser#new_context) method. Non-persistent browser
contexts don't write any browsing data to disk.

```ruby
Expand Down
1 change: 0 additions & 1 deletion documentation/docs/api/cdp_session.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ sidebar_position: 10

# CDPSession

- extends: [EventEmitter]

The [CDPSession](./cdp_session) instances are used to talk raw Chrome Devtools Protocol:
- protocol methods can be called with `session.send_message` method.
Expand Down
1 change: 0 additions & 1 deletion documentation/docs/api/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ sidebar_position: 10

# Page

- extends: [EventEmitter]

Page provides methods to interact with a single tab in a [Browser](./browser), or an
[extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One [Browser](./browser)
Expand Down
12 changes: 9 additions & 3 deletions documentation/docs/api/route.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def continue(headers: nil, method: nil, postData: nil, url: nil)
```


Continues route's request with optional overrides.
Sends route's request to the network with optional overrides.

**Usage**

Expand All @@ -47,20 +47,24 @@ page.route("**/*", method(:handle))

Note that any overrides such as `url` or `headers` only apply to the request being routed. If this request results in a redirect, overrides will not be applied to the new redirected request. If you want to propagate a header through redirects, use the combination of [Route#fetch](./route#fetch) and [Route#fulfill](./route#fulfill) instead.

[Route#continue](./route#continue) will immediately send the request to the network, other matching handlers won't be invoked. Use [Route#fallback](./route#fallback) If you want next matching handler in the chain to be invoked.

## fallback

```
def fallback(headers: nil, method: nil, postData: nil, url: nil)
```


Continues route's request with optional overrides. The method is similar to [Route#continue](./route#continue) with the difference that other matching handlers will be invoked before sending the request.

**Usage**

When several routes match the given pattern, they run in the order opposite to their registration.
That way the last registered route can always override all the previous ones. In the example below,
request will be handled by the bottom-most handler first, then it'll fall back to the previous one and
in the end will be aborted by the first registered route.

**Usage**

```ruby
page.route("**/*", -> (route,_) { route.abort }) # Runs last.
page.route("**/*", -> (route,_) { route.fallback }) # Runs second.
Expand Down Expand Up @@ -114,6 +118,8 @@ end
page.route("**/*", method(:handle))
```

Use [Route#continue](./route#continue) to immediately send the request to the network, other matching handlers won't be invoked in that case.

## fetch

```
Expand Down
24 changes: 23 additions & 1 deletion lib/playwright/channel_owners/api_request_context.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'base64'
require 'cgi'

module Playwright
define_channel_owner :APIRequestContext do
Expand Down Expand Up @@ -112,7 +113,7 @@ def fetch(
headers_obj = headers || request&.headers
fetch_params = {
url: url || request.url,
params: object_to_array(params),
params: map_params_to_array(params),
method: method || request&.method || 'GET',
headers: headers_obj ? HttpHeaders.new(headers_obj).as_serialized : nil,
}
Expand Down Expand Up @@ -179,6 +180,27 @@ def fetch(
}
end

private def map_params_to_array(params)
if params.is_a?(String)
unless params.start_with?('?')
raise ArgumentError.new("Query string must start with '?'")
end
query_string_to_array(params[1..-1])
else
object_to_array(params)
end
end

private def query_string_to_array(query_string)
params = CGI.parse(query_string)

params.map do |key, values|
values.map do |value|
{ name: key, value: value }
end
end.flatten
end

private def object_to_array(hash)
hash&.map do |key, value|
{ name: key, value: value.to_s }
Expand Down
4 changes: 2 additions & 2 deletions lib/playwright/version.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Playwright
VERSION = '1.46.0'
COMPATIBLE_PLAYWRIGHT_VERSION = '1.46.1'
VERSION = '1.47.0'
COMPATIBLE_PLAYWRIGHT_VERSION = '1.47.1'
end
39 changes: 34 additions & 5 deletions spec/integration/browser_context/fetch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,52 @@
put: :put,
}.freeze
%i(fetch delete get head patch post put).each do |http_method|
it "#{http_method} should support queryParams" do
it "#{http_method} should support params passed as object (Hash)" do
promise = Concurrent::Promises.resolvable_future
sinatra.send(SINATRA_MAP[http_method], '/empty.html') do
promise.fulfill(params.dup)
end

with_context do |context|
response = with_context do |context|
context.request.send(
http_method,
"#{server_empty_page}?p1=foo",
params: { p1: 'v1', парам2: 'знач2'},
"#{server_empty_page}?p1[]=foo",
params: { "p1[]": 'v1', парам2: 'знач2'},
)
end

params = promise.value!
expect(params['p1']).to eq('v1')
expect(params['p1']).to eq(['foo', 'v1'])
expect(params['парам2']).to eq('знач2')

response_query = URI(response.url).query
response_params = Rack::Utils.parse_nested_query(response_query)
expect(response_params['p1']).to eq(['foo', 'v1'])
expect(response_params['парам2']).to eq('знач2')
end

it "#{http_method} should support params passed as string" do
promise = Concurrent::Promises.resolvable_future
sinatra.send(SINATRA_MAP[http_method], '/empty.html') do
promise.fulfill(params.dup)
end

response = with_context do |context|
context.request.send(
http_method,
"#{server_empty_page}?param1[]=foo",
params: '?param1[]=value1&param1[]=value2&парам2=знач2',
)
end

params = promise.value!
expect(params['param1']).to eq(['foo', 'value1', 'value2'])
expect(params['парам2']).to eq('знач2')

response_query = URI(response.url).query
response_params = Rack::Utils.parse_nested_query(response_query)
expect(response_params['param1']).to eq(['foo', 'value1', 'value2'])
expect(response_params['парам2']).to eq('знач2')
end

it "#{http_method} should support failOnStatusCode" do
Expand Down
23 changes: 12 additions & 11 deletions spec/integration/client_certificates_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
page = context.new_page
expect {
page.goto(server_empty_page)
}.to raise_error(/net::ERR_CONNECTION_RESET|net::ERR_SOCKET_NOT_CONNECTED|The network connection was lost|Connection terminated unexpectedly/)
}.to raise_error(/net::ERR_EMPTY_RESPONSE|net::ERR_CONNECTION_RESET|net::ERR_SOCKET_NOT_CONNECTED|The network connection was lost|Connection terminated unexpectedly/)
end
end

Expand Down Expand Up @@ -155,11 +155,12 @@ def asset(path)
passphrase: 'this-password-is-incorrect'
}]
}
with_context(**options) do |context|
page = context.new_page
page.goto(server_empty_page)
expect(page.content).to include('mac verify failure')
end

expect {
with_context(**options) do |context|
page = context.new_page
end
}.to raise_error(/mac verify failure/)
end

it 'should fail with matching certificates in legacy pfx format', skip: ENV['CI'] do
Expand All @@ -171,10 +172,10 @@ def asset(path)
passphrase: 'secure'
}]
}
with_context(**options) do |context|
page = context.new_page
page.goto(server_empty_page)
expect(page.content).to include('Unsupported TLS certificate')
end
expect {
with_context(**options) do |context|
page = context.new_page
end
}.to raise_error(/Unsupported TLS certificate/)
end
end

0 comments on commit 26b2ae1

Please sign in to comment.