Frame
At every point of time, page exposes its current frame tree via the Page#main_frame and Frame#child_frames methods.
Frame object's lifecycle is controlled by three events, dispatched on the page object:
- [
event: Page.frameAttached] - fired when the frame gets attached to the page. A Frame can be attached to the page only once. - [
event: Page.frameNavigated] - fired when the frame commits navigation to a different URL. - [
event: Page.frameDetached] - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
An example of dumping frame tree:
def dump_frame_tree(frame, indent = 0)
puts "#{' ' * indent}#{frame.name}@#{frame.url}"
frame.child_frames.each do |child|
dump_frame_tree(child, indent + 2)
end
end
page.goto("https://www.theverge.com")
dump_frame_tree(page.main_frame)
add_script_tag
def add_script_tag(content: nil, path: nil, type: nil, url: nil)
Returns the added tag when the script's onload fires or when the script content was injected into frame.
Adds a <script> tag into the page with the desired url or content.
add_style_tag
def add_style_tag(content: nil, path: nil, url: nil)
Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
Adds a <link rel="stylesheet"> tag into the page with the desired url or a <style type="text/css"> tag with the
content.
check
def check(
selector,
force: nil,
noWaitAfter: nil,
position: nil,
strict: nil,
timeout: nil,
trial: nil)
This method checks an element matching selector by performing the following steps:
- Find an element matching
selector. If there is none, wait until a matching element is attached to the DOM. - Ensure that matched element is a checkbox or a radio input. If not, this method throws. If the element is already checked, this method returns immediately.
- Wait for actionability checks on the matched element, unless
forceoption is set. If the element is detached during the checks, the whole action is retried. - Scroll the element into view if needed.
- Use Page#mouse to click in the center of the element.
- Ensure that the element is now checked. If not, this method throws.
When all steps combined have not finished during the specified timeout, this method throws a
TimeoutError. Passing zero timeout disables this.
child_frames
def child_frames
click
def click(
selector,
button: nil,
clickCount: nil,
delay: nil,
force: nil,
modifiers: nil,
noWaitAfter: nil,
position: nil,
strict: nil,
timeout: nil,
trial: nil)
This method clicks an element matching selector by performing the following steps:
- Find an element matching
selector. If there is none, wait until a matching element is attached to the DOM. - Wait for actionability checks on the matched element, unless
forceoption is set. If the element is detached during the checks, the whole action is retried. - Scroll the element into view if needed.
- Use Page#mouse to click in the center of the element, or the specified
position. - Wait for initiated navigations to either succeed or fail, unless
noWaitAfteroption is set.
When all steps combined have not finished during the specified timeout, this method throws a
TimeoutError. Passing zero timeout disables this.
content
def content
Gets the full HTML contents of the frame, including the doctype.
dblclick
def dblclick(
selector,
button: nil,
delay: nil,
force: nil,
modifiers: nil,
noWaitAfter: nil,
position: nil,
strict: nil,
timeout: nil,
trial: nil)
This method double clicks an element matching selector by performing the following steps:
- Find an element matching
selector. If there is none, wait until a matching element is attached to the DOM. - Wait for actionability checks on the matched element, unless
forceoption is set. If the element is detached during the checks, the whole action is retried. - Scroll the element into view if needed.
- Use Page#mouse to double click in the center of the element, or the specified
position. if the first click of thedblclick()triggers a navigation event, this method will throw.
When all steps combined have not finished during the specified timeout, this method throws a
TimeoutError. Passing zero timeout disables this.
NOTE: frame.dblclick() dispatches two click events and a single dblclick event.
dispatch_event
def dispatch_event(
selector,
type,
eventInit: nil,
strict: nil,
timeout: nil)
The snippet below dispatches the click event on the element. Regardless of the visibility state of the element, click
is dispatched. This is equivalent to calling
element.click().
Usage
frame.dispatch_event("button#submit", "click")
Under the hood, it creates an instance of an event based on the given type, initializes it with
eventInit properties and dispatches it on the element. Events are composed, cancelable and bubble by
default.
Since eventInit is event-specific, please refer to the events documentation for the lists of initial
properties:
- DeviceMotionEvent
- DeviceOrientationEvent
- DragEvent
- Event
- FocusEvent
- KeyboardEvent
- MouseEvent
- PointerEvent
- TouchEvent
- WheelEvent
You can also specify JSHandle as the property value if you want live objects to be passed into the event:
data_transfer = frame.evaluate_handle("new DataTransfer()")
frame.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_transfer })
drag_and_drop
def drag_and_drop(
source,
target,
force: nil,
noWaitAfter: nil,
sourcePosition: nil,
steps: nil,
strict: nil,
targetPosition: nil,
timeout: nil,
trial: nil)
eval_on_selector
def eval_on_selector(selector, expression, arg: nil, strict: nil)
Returns the return value of expression.
The method finds an element matching the specified selector within the frame and passes it as a first argument to
expression. If no
elements match the selector, the method throws an error.
If expression returns a Promise, then Frame#eval_on_selector would wait for the promise to resolve and return its
value.
Usage
search_value = frame.eval_on_selector("#search", "el => el.value")
preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", arg: "hello")
eval_on_selector_all
def eval_on_selector_all(selector, expression, arg: nil)
Returns the return value of expression.
The method finds all elements matching the specified selector within the frame and passes an array of matched elements
as a first argument to expression.
If expression returns a Promise, then Frame#eval_on_selector_all would wait for the promise to resolve and return its
value.
Usage
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", arg: 10)
evaluate
def evaluate(expression, arg: nil)
Returns the return value of expression.
If the function passed to the Frame#evaluate returns a Promise, then Frame#evaluate would wait for the promise to resolve and return its value.
If the function passed to the Frame#evaluate returns a non-Serializable value, then
Frame#evaluate returns undefined. Playwright also supports transferring some
additional values that are not serializable by JSON: -0, NaN, Infinity, -Infinity.
Usage
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", arg: [7, 8])
puts result # => "56"
A string can also be passed in instead of a function.
puts frame.evaluate("1 + 2") # => 3
x = 10
puts frame.evaluate("1 + #{x}") # => "11"
ElementHandle instances can be passed as an argument to the Frame#evaluate:
body_handle = frame.evaluate_handle("document.body")
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
body_handle.dispose
evaluate_handle
def evaluate_handle(expression, arg: nil)
Returns the return value of expression as a JSHandle.
The only difference between Frame#evaluate and Frame#evaluate_handle is that Frame#evaluate_handle returns JSHandle.
If the function, passed to the Frame#evaluate_handle, returns a Promise, then Frame#evaluate_handle would wait for the promise to resolve and return its value.
Usage
a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object.
A string can also be passed in instead of a function.
a_handle = frame.evaluate_handle("document") # handle for the "document"
JSHandle instances can be passed as an argument to the Frame#evaluate_handle:
a_handle = frame.evaluate_handle("document.body")
result_handle = frame.evaluate_handle("body => body.innerHTML", arg: a_handle)
puts result_handle.json_value
result_handle.dispose
fill
def fill(
selector,
value,
force: nil,
noWaitAfter: nil,
strict: nil,
timeout: nil)
This method waits for an element matching selector, waits for actionability checks, focuses the element, fills it and triggers an input event after filling. Note that you can pass an empty string to clear the input field.
If the target element is not an <input>, <textarea> or [contenteditable] element, this method throws an error. However, if the element is inside the <label> element that has an associated control, the control will be filled instead.
To send fine-grained keyboard events, use Locator#press_sequentially.
focus
def focus(selector, strict: nil, timeout: nil)
This method fetches an element with selector and focuses it. If there's no element matching
selector, the method waits until a matching element appears in the DOM.
frame_element
def frame_element
Returns the frame or iframe element handle which corresponds to this frame.
This is an inverse of ElementHandle#content_frame. Note that returned handle actually belongs to the parent frame.
This method throws an error if the frame has been detached before frameElement() returns.
Usage
frame_element = frame.frame_element
content_frame = frame_element.content_frame
puts frame == content_frame # => true
frame_locator
def frame_locator(selector)
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in that iframe.
Usage
Following snippet locates element with text "Submit" in the iframe with id my-frame, like <iframe id="my-frame">:
locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
locator.click
get_attribute
def get_attribute(selector, name, strict: nil, timeout: nil)
Returns element attribute value.
get_by_alt_text
def get_by_alt_text(text, exact: nil)
Allows locating elements by their alt text.
Usage
For example, this method will find the image by alt text "Playwright logo":
<img alt='Playwright logo'>
page.get_by_alt_text("Playwright logo").click
get_by_label
def get_by_label(text, exact: nil)
Allows locating input elements by the text of the associated <label> or aria-labelledby element, or by the aria-label attribute.
Usage
For example, this method will find inputs by label "Username" and "Password" in the following DOM:
<input aria-label="Username">
<label for="password-input">Password:</label>
<input id="password-input">
page.get_by_label("Username").fill("john")
page.get_by_label("Password").fill("secret")
get_by_placeholder
def get_by_placeholder(text, exact: nil)
Allows locating input elements by the placeholder text.
Usage
For example, consider the following DOM structure.
<input type="email" placeholder="name@example.com" />
You can fill the input after locating it by the placeholder text:
page.get_by_placeholder("name@example.com").fill("playwright@microsoft.com")
get_by_role
def get_by_role(
role,
checked: nil,
description: nil,
disabled: nil,
exact: nil,
expanded: nil,
includeHidden: nil,
level: nil,
name: nil,
pressed: nil,
selected: nil)
Allows locating elements by their ARIA role, ARIA attributes and accessible name.
Usage
Consider the following DOM structure.
<h3>Sign up</h3>
<label>
<input type="checkbox" /> Subscribe
</label>
<br/>
<button>Submit</button>
You can locate each element by its implicit role:
page.get_by_role("heading", name: "Sign up").visible? # => true
page.get_by_role("checkbox", name: "Subscribe").check
page.get_by_role("button", name: /submit/i).click
Details
Role selector does not replace accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
Many html elements have an implicitly defined role that is recognized by the role selector. You can find all the supported roles here. ARIA guidelines do not recommend duplicating implicit roles and attributes by setting role and/or aria-* attributes to default values.
get_by_test_id
def get_by_test_id(testId)
alias: get_by_testid
Locate element by the test id.
Usage
Consider the following DOM structure.
<button data-testid="directions">Itinéraire</button>
You can locate the element by its test id:
page.get_by_test_id("directions").click
Details
By default, the data-testid attribute is used as a test id. Use Selectors#set_test_id_attribute to configure a different test id attribute if necessary.