diff --git a/CHANGELOG.md b/CHANGELOG.md index 33f2881a..9fe947e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ `go_to` instead ### Fixed +- `evaluate` raised `NoMethodError` when a node inside a `Map` or `Set` was also referenced elsewhere in the result - `headers.clear` kept sending the old headers until the next `add` or `set`, and kept the user agent and language they set. Now it clears them in Chrome right away - `headers.add` and `headers.set` reset a user agent or language set with `network.emulate`, and made Chrome stop diff --git a/lib/ferrum/frame/runtime.rb b/lib/ferrum/frame/runtime.rb index 39da10f4..c28e2298 100644 --- a/lib/ferrum/frame/runtime.rb +++ b/lib/ferrum/frame/runtime.rb @@ -449,6 +449,9 @@ def convert(serialized, references, path, converted) value.to_h { |k, v| [k, deserialize(v, references, path, converted)] } when "node" Node.new(self, value) + when "map", "set" + value.flatten(1).each { |v| deserialize(v, references, path, converted) if v.is_a?(Hash) } + {} else {} end diff --git a/spec/frame/runtime_spec.rb b/spec/frame/runtime_spec.rb index 7c1366f0..2bce37a5 100644 --- a/spec/frame/runtime_spec.rb +++ b/spec/frame/runtime_spec.rb @@ -269,6 +269,32 @@ expect(browser.evaluate("window")).to eq({}) end + it "returns a node shared with a map" do + browser.go_to("/index") + + result = browser.evaluate("(() => { const el = document.body; return [new Map([['k', el]]), { el }] })()") + + expect(result.first).to eq({}) + expect(result.last["el"]).to be_a(Ferrum::Node).and have_attributes(tag_name: "body") + end + + it "returns a node shared with a set" do + browser.go_to("/index") + + result = browser.evaluate("(() => { const el = document.body; return [new Set([el]), [el]] })()") + + expect(result.first).to eq({}) + expect(result.last.first).to be_a(Ferrum::Node).and have_attributes(tag_name: "body") + end + + it "returns a node shared with a map nested in an object" do + browser.go_to("/index") + + result = browser.evaluate("(() => { const el = document.body; return { m: new Map([[1, { n: el }]]), el } })()") + + expect(result["el"]).to be_a(Ferrum::Node) + end + it "fetches the whole result tree with one command" do allow(browser.page).to receive(:command).and_call_original diff --git a/spec/network/intercepted_request_spec.rb b/spec/network/intercepted_request_spec.rb index d64202a8..38a3283d 100644 --- a/spec/network/intercepted_request_spec.rb +++ b/spec/network/intercepted_request_spec.rb @@ -74,7 +74,7 @@ page.go_to expect(network.status).to eq(201) - expect(last_exchange.response.headers).to include("X-Ferrum" => "yes") + expect(network.response.headers).to include("X-Ferrum" => "yes") expect(page.body).to include("created") end diff --git a/spec/node_spec.rb b/spec/node_spec.rb index 1e5546be..30f50ff8 100644 --- a/spec/node_spec.rb +++ b/spec/node_spec.rb @@ -1294,7 +1294,7 @@ def rect it "raises CoordinatesNotFoundError for a hidden node" do node = browser.at_css("#nav") - node.execute("this.style.display = 'none'") + node.execute("this.style.display = 'none'; this.offsetHeight") expect { node.find_position }.to raise_error(Ferrum::CoordinatesNotFoundError) end