rplaywright is an R package developed as part of my participation in the rOpenSci Champions Program. It is designed to seamlessly bridge with the NodeJS library, Playwright, enabling simplified web testing and automation for R users. This package aims to provide R users with a comprehensive toolkit for interacting with web browsers programmatically, allowing for tasks such as browser automation, web scraping, and end-to-end testing directly from within the R environment. rplaywright offers a user-friendly interface and robust functionality for handling complex web interactions, making it an invaluable tool for both beginners and experienced developers alike.
Installation
You can install the development version of rplaywright from GitHub with:
devtools::install_github("erikaris/rplaywright")
rplaywright::install_rplaywright(force = TRUE)
Browser
Launch new browser instance
chrome <- rplaywright::new_chromium()
firefox <- rplaywright::new_firefox()
webkit <- rplaywright::new_webkit()
Browser Context
BrowserContexts provide a way to operate multiple independent browser sessions.
context <- chrome$new_context()$then()
Page
Page provides methods to interact with a single tab in a Browser, or an extension background page in Chromium. One Browser instance might have multiple Page instances.
page <- context$new_page()$then()
add_init_script
Adds a script which would be evaluated in one of the following scenarios:
- Whenever the page is navigated.
- Whenever the child frame is attached or navigated. In this case, the script is evaluated in the context of the newly attached frame.
The script is evaluated after the document was created but before any of its scripts were run. This is useful to amend the JavaScript environment, e.g. to seed Math.random.
page$add_init_script(list(path=normalizePath("./examples/preload.js")))
page$goto("https://playwright.dev/")$then()
result_from_preload <- page$evaluate("() => Math.random()")$then()
add_locator_handler
When testing a web page, sometimes unexpected overlays like a “Sign up” dialog appear and block actions you want to automate, e.g. clicking a button. These overlays don’t always show up in the same way or at the same time, making them tricky to handle in automated tests.
This method lets you set up a special function, called a handler, that activates when it detects that overlay is visible. The handler’s job is to remove the overlay, allowing your test to continue as if the overlay wasn’t there.
Things to keep in mind:
- When an overlay is shown predictably, we recommend explicitly waiting for it in your test and dismissing it as a part of your normal test flow, instead of using page.addLocatorHandler().
- Playwright checks for the overlay every time before executing or retrying an action that requires an actionability check, or before performing an auto-waiting assertion check. When overlay is visible, Playwright calls the handler first, and then proceeds with the action/assertion. Note that the handler is only called when you perform an action/assertion - if the overlay becomes visible but you don’t perform any actions, the handler will not be triggered.
- After executing the handler, Playwright will ensure that overlay that triggered the handler is not visible anymore. You can opt-out of this behavior with noWaitAfter.
- The execution time of the handler counts towards the timeout of the action/assertion that executed the handler. If your handler takes too long, it might cause timeouts.
- You can register multiple handlers. However, only a single handler will be running at a time. Make sure the actions within a handler don’t depend on another handler.
page$add_locator_handler()
page$goto("https://playwright.dev/")$then()
add_script_tag
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the first non-redirect response.
page$goto("https://playwright.dev/")$then()
page$add_script_tag(list(path=normalizePath("./examples/preload.js")))$then()
page$add_script_tag(list(content="const greet = () => console.log('hello')"))$then()
add_style_tag
Adds a <link rel="stylesheet">
tag into the page with the desired url or a <style type="text/css">
tag with the content. Returns the added tag when the stylesheet’s onload fires or when the CSS content was injected into frame.
page$goto("https://playwright.dev/")$then()
page$add_style_tag(list(path=normalizePath("./examples/style.css")))$then()
page$add_style_tag(list(content=
".highlight_gXVj {
color: red;
}"))$then()
bring_to_front
Brings page to front (activates tab).
page2 <- context$new_page()$then()
page2$goto("https://demo.playwright.dev/todomvc/#/")$then()
page$bring_to_front()$then()
close
If runBeforeUnload is false, does not run any unload handlers and waits for the page to be closed. If runBeforeUnload is true the method will run unload handlers, but will not wait for the page to close.
By default, page.close() does not run beforeunload handlers.
page2$close()
content
Gets the full HTML contents of the page, including the doctype.
content <- page$content()$then()
drag_and_drop
This method drags the source element to the target element. It will first move to the source element, perform a mousedown, then move to the target element and perform a mouseup.
page$drag_and_drop("#source", "#target")$then()
emulate_media
This method changes the CSS media type through the media argument, and/or the ‘prefers-colors-scheme’ media feature, using the colorScheme argument.
page$emulate_media(list(media="print"))$then()
page$evaluate("() => matchMedia('screen').matches")$then()
page$evaluate("() => matchMedia('print').matches")$then()
evaluate
Returns the value of the pageFunction invocation.
If the function passed to the page.evaluate() returns a Promise, then page.evaluate() would wait for the promise to resolve and return its value.
If the function passed to the page.evaluate() returns a non-Serializable value, then page.evaluate() resolves to undefined. Playwright also supports transferring some additional values that are not serializable by JSON: -0, NaN, Infinity, -Infinity.
page$emulate_media(list(media="print"))$then()
page$evaluate("() => matchMedia('screen').matches")$then()
page$evaluate("() => matchMedia('print').matches")$then()
page$evaluate(
"([x, y]) => {
return Promise.resolve(x * y);
}",
c(7, 8)
)$then()
page$evaluate(
"({ x, y }) => {
return Promise.resolve(x * y);
}",
list(x=7, y=10)
)$then()
evaluate_handle
Returns the value of the pageFunction invocation as a JSHandle.
The only difference between page.evaluate() and page.evaluateHandle() is that page.evaluateHandle() returns JSHandle.
If the function passed to the page.evaluateHandle() returns a Promise, then page.evaluateHandle() would wait for the promise to resolve and return its value.
page$evaluate_handle()
expose_binding
The method adds a function called name on the window object of every frame in this page. When called, the function executes callback and returns a Promise which resolves to the return value of callback. If the callback returns a Promise, it will be awaited.
The first argument of the callback function contains information about the caller: { browserContext: BrowserContext, page: Page, frame: Frame }.
page$expose_binding("pageURL", "({ page }) => page.url()")
page$set_content("
<script>
async function onClick() {
document.querySelector('div').textContent = await window.pageURL();
}
</script>
<button onclick='onClick()'>Click me</button>
<div></div>"
)$then()
page$get_by_role("button")$click("button")$then()
expose_function
The method adds a function called name on the window object of every frame in the page. When called, the function executes callback and returns a Promise which resolves to the return value of callback.
If the callback returns a Promise, it will be awaited.
page$expose_function("base64", "(text) => btoa(text)")
page$set_content("
<script>
async function onClick() {
document.querySelector('div').textContent = await base64('PLAYWRIGHT');
}
</script>
<button onclick='onClick()'>Click me</button>
<div></div>"
)$then()
page$get_by_role("button")$click("button")$then()
frame
Returns frame matching the specified criteria. Either name or url must be specified.
page$goto("https://playwright.dev/")$then()
frame <- page$frame("main")
frame_locator
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in that iframe.
page$set_content(
"<iframe id='myframe'>
<button>Button</button>
</iframe>"
)
myframe <- page$frame_locator("#myframe")
frames
An array of all frames attached to the page.
page$set_content(
"<iframe id='myframe'>
<button>Button</button>
</iframe>"
)
frames <- page$frames()
get_by_alt_text
Allows locating elements by their alt text.
page_2 <- context$new_page()$then()
page_2$set_content("<img alt='Playwright logo'>")
page_2$get_by_alt_text("link")$click(list(timeout=100))$then()
get_by_label
Allows locating input elements by the text of the associated
page_2 <- context$new_page()$then()
page_2$set_content('<input aria-label="Username"></input>
<label for="password-input">Password:</label>
<input id="password-input"></input>')
page_2$get_by_label("Username")$fill("John", list(timeout=100))$then()
get_by_placeholder
Allows locating input elements by the placeholder text.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="email" placeholder="name@example.com"></input>')
page_2$get_by_placeholder("name@example.com")$fill("playwright@microsoft.com", list(timeout=100))$then()
get_by_role
Allows locating elements by their ARIA role, ARIA attributes and accessible name.
get_by_test_id
Locate element by the test id.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
page_2$get_by_test_id("directions")$click(list(timeout=100))$then()
get_by_text
Allows locating elements that contain given text.
See also locator.filter() that allows to match by another criteria, like an accessible role, and then filter by the text content.
get_by_title
Allows locating elements by their title attribute.
page_2 <- context$new_page()$then()
page_2$set_content("<span title='Issues count'>25 issues</span>")
get_by_title <- page_2$get_by_title("Issues count")$text_content()$then()
go_back
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If cannot go back, returns null.
Navigate to the previous page in history.
page$goto("https://playwright.dev/docs/api/class-page#page-get-by-title")
page$goto("https://playwright.dev/docs/api/class-page#page-go-back")
page$go_back()$then()
go_forward
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If cannot go forward, returns null.
Navigate to the next page in history.
page$goto("https://playwright.dev/docs/api/class-page#page-get-by-title")
page$goto("https://playwright.dev/docs/api/class-page#page-go-back")
page$go_back()$then()
page$go_forward()$then()
goto
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the first non-redirect response.
resp <- page$goto("https://playwright.dev/")$then()
resp$status()
is_closed
Indicates that the page has been closed.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
page2$close()$then()
is_closed <- page2$is_closed()
locator
The method finds an element matching the specified selector in the locator’s subtree. It also accepts filter options, similar to locator.filter() method.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
locator_inner_text <- page_2$locator('[data-testid="directions"]')$inner_text(list(timeout=100))$then()
main_frame
The page’s main frame. Page is guaranteed to have a main frame which persists during navigations.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
main_frame <- page2$main_frame()
opener
Returns the opener for popup pages and null for others. If the opener has been closed already the returns null.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
opener <- page2$opener()$then()
pause
Pauses script execution. Playwright will stop executing the script and wait for the user to either press ‘Resume’ button in the page overlay or to call playwright.resume() in the DevTools console.
User can inspect selectors or perform manual steps while paused. Resume will continue running the original script from the place it was paused.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
page2$pause()$then()
Returns the PDF buffer.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
page2$emulate_media(list(media="screen"))$then()
pdf <- page2$pdf()$then()
reload
This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
page2 <- context$new_page()$then()
page2$goto("https://playwright.dev/")$then()
page2$reload()$then()$status()
remove_locator_handler
Removes all locator handlers added by page.addLocatorHandler() for a specific locator.
page$remove_locator_handler()
page$goto("https://playwright.dev/")$then()
route
Routing provides the capability to modify network requests that are made by a page.
Once routing is enabled, every request matching the url pattern will stall unless it’s continued, fulfilled or aborted.
page$route("**/*.{png,jpg,jpeg}", "route => route.abort()")$then()
page$goto("https://playwright.dev/")$then()
route_from_h_a_r
If specified the network requests that are made in the page will be served from the HAR file. Read more about Replaying from HAR.
Playwright will not serve requests intercepted by Service Worker from the HAR file. See this issue. We recommend disabling Service Workers when using request interception by setting Browser.newContext.serviceWorkers to ‘block’.
page$route_from_h_a_r("/path/to/har")
page$goto("https://playwright.dev/")$then()
screenshot
Returns the buffer with the captured screenshot.
page$goto("https://playwright.dev/")$then()
page_screenshot <- page$screenshot()$then()
set_content
This method internally calls document.write(), inheriting all its specific characteristics and behaviors.
page$set_content('<button data-testid="directions">Itinéraire</button>')$then()
set_default_navigation_timeout
This setting will change the default maximum navigation time for the following methods and related shortcuts:
page.goBack() page.goForward() page.goto() page.reload() page.setContent() page.waitForNavigation() page.waitForURL()
page$set_default_navigation_timeout(100)
set_default_timeout
This setting will change the default maximum time for all the methods accepting timeout option.
page$set_default_timeout(100)
set_extra_h_t_t_p_headers
The extra HTTP headers will be sent with every request the page initiates.
page$set_extra_h_t_t_p_headers(list("setCookies", "token=token"))$then()
page$set_content('<button data-testid="directions">Itinéraire</button>')$then()
set_viewport_size
In the case of multiple pages in a single browser, each page can have its own viewport size. However, browser.newContext() allows to set viewport size (and more) for all pages in the context at once.
page.setViewportSize() will resize the page. A lot of websites don’t expect phones to change size, so you should set the viewport size before navigating to the page. page.setViewportSize() will also reset screen size, use browser.newContext() with screen and viewport parameters if you need better control of these properties.
page$set_viewport_size(list(width=800, height=600))$then()
page$goto("https://playwright.dev/")$then()
title
Returns the page’s title.
page$goto("https://playwright.dev/")$then()
title <- page$title()$then()
unroute
Removes a route created with page.route(). When handler is not specified, removes all routes for the url.
page$unroute("**/*.{png,jpg,jpeg}", "route => route.abort()")$then()
page$goto("https://playwright.dev/")$then()
unroute_all
Removes all routes created with page.route() and page.routeFromHAR().
page$unroute_all()$then()
page$goto("https://playwright.dev/")$then()
url
page$goto("https://playwright.dev/")$then()
url <- page$url()
video
Video object associated with this page.
page$goto("https://playwright.dev/")$then()
video <- page$video()
viewport_size
page$goto("https://playwright.dev/")$then()
viewport_size <- page$viewport_size()
wait_for_event
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy value. Will throw an error if the page is closed before the event is fired. Returns the event data value.
ev_promise <- page$wait_for_event("load")
page$goto("https://playwright.dev/")$then()
ev <- ev_promise$then()
wait_for_function
Returns when the pageFunction returns a truthy value. It resolves to a JSHandle of the truthy value.
fn_promise <- page$wait_for_function("() => window.innerWidth < 100")
page$set_viewport_size(list(width=50, height=50))$then()
js <- fn_promise$then()
wait_for_load_state
Returns when the required load state has been reached.
This resolves when the page reaches a required load state, load by default. The navigation must have been committed when this method is called. If current document has already reached the required state, resolves immediately.
ev_promise <- page$wait_for_load_state("load")
page$goto("https://playwright.dev/")$then()
ev <- ev_promise$then()
wait_for_request
Waits for the matching request and returns it. See waiting for event for more details about events.
req_promise <- page$wait_for_request("(req) => req.url().includes('playwright.dev')")
page$goto("https://playwright.dev/")$then()
req <- req_promise$then()
wait_for_response
Returns the matched response. See waiting for event for more details about events.
resp_promise <- page$wait_for_response("(resp) => resp.url().includes('playwright.dev')")
page$goto("https://playwright.dev/")$then()
resp <- resp_promise$then()
wait_for_u_r_l
Waits for the main frame to navigate to the given URL.
resp_promise <- page$wait_for_u_r_l("https://playwright.dev/")
page$goto("https://playwright.dev/")$then()
resp_promise$then()
workers
This method returns all of the dedicated WebWorkers associated with the page.
page$goto("https://playwright.dev/")$then()
workers <- page$workers()
Locator
Locators are the central piece of Playwright’s auto-waiting and retry-ability. In a nutshell, locators represent a way to find element(s) on the page at any moment.
all
When the locator points to a list of elements, this returns an array of locators, pointing to their respective elements.
all_links <- page$get_by_role("link")$all()$then()
all_inner_texts
Returns an array of node.innerText values for all matching nodes.
all_inner_texts <- page$get_by_role("link")$all_inner_texts()$then()
all_text_contents
Returns an array of node.textContent values for all matching nodes.
all_text_contents <- page$get_by_role("link")$all_text_contents()$then()
and
Creates a locator that matches both this locator and the argument locator.
and_unimplemented <- page$get_by_role("link")$and()
bounding_box
This method returns the bounding box of the element matching the locator, or null if the element is not visible. The bounding box is calculated relative to the main frame viewport - which is usually the same as the browser window.
bounding_box <- page$get_by_role("link", list(name="Get started"))$bounding_box()$then()
check
Ensure that checkbox or radio element is checked.
page$get_by_role("checkbox")$check(list(timeout=100))$then()
click
Click an element.
content_frame
Returns a FrameLocator object pointing to the same iframe as this locator.
Useful when you have a Locator object obtained somewhere, and later on would like to interact with the content inside the frame.
For a reverse operation, use frameLocator.owner().
content_frame_unimplemented <- page$get_by_role("link")$content_frame()
count
Returns the number of elements matching the locator.
count <- page$get_by_role("link")$count()$then()
dblclick
Double-click an element.
dispatch_event
Programmatically dispatch an event on the matching element.
drag_to
Drag the source element towards the target element and drop it.
drag_to_unimplemented <- page$get_by_role("link")$drag_to()
evaluate
Execute JavaScript code in the page, taking the matching element as an argument.
evaluate_unimplemented <- page$get_by_role("link")$evaluate()
evaluate_all
Execute JavaScript code in the page, taking all matching elements as an argument.
evaluate_all_unimplemented <- page$get_by_role("link")$evaluate_all()
evaluate_handle
Execute JavaScript code in the page, taking the matching element as an argument, and return a JSHandle with the result.
evaluate_handle_unimplemented <- page$get_by_role("link")$evaluate_handle()
fill
Set a value to the input field.
page$get_by_role("textbox")$fill("example value", list(timeout=100))$then()
filter
This method narrows existing locator according to the options, for example filters by text. It can be chained to filter multiple times.
filter_unimplemented <- page$get_by_role("link")$filter()
frame_locator
When working with iframes, you can create a frame locator that will enter the iframe and allow locating elements in that iframe:
frame_locator_unimplemented <- page$get_by_role("link")$frame_locator()
get_attribute
Returns the matching element’s attribute value.
attribute <- page$get_by_role("link")$first()$get_attribute("title")$then()
get_by_alt_text
Allows locating elements by their alt text.
page_2 <- context$new_page()$then()
page_2$set_content("<img alt='Playwright logo'>")
page_2$get_by_alt_text("link")$click(list(timeout=100))$then()
get_by_label
Allows locating input elements by the text of the associated
page_2 <- context$new_page()$then()
page_2$set_content('<input aria-label="Username"></input>
<label for="password-input">Password:</label>
<input id="password-input"></input>')
page_2$get_by_label("Username")$fill("John", list(timeout=100))$then()
get_by_placeholder
Allows locating input elements by the placeholder text.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="email" placeholder="name@example.com"></input>')
page_2$get_by_placeholder("name@example.com")$fill("playwright@microsoft.com", list(timeout=100))$then()
get_by_role
Allows locating elements by their ARIA role, ARIA attributes and accessible name.
get_by_test_id
Locate element by the test id.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
page_2$get_by_test_id("directions")$click(list(timeout=100))$then()
get_by_text
Allows locating elements that contain given text.
See also locator.filter() that allows to match by another criteria, like an accessible role, and then filter by the text content.
get_by_title
Allows locating elements by their title attribute.
page_2 <- context$new_page()$then()
page_2$set_content("<span title='Issues count'>25 issues</span>")
get_by_title <- page_2$get_by_title("Issues count")$text_content()$then()
highlight
Highlight the corresponding element(s) on the screen. Useful for debugging, don’t commit the code that uses locator.highlight().
page_2 <- context$new_page()$then()
page_2$set_content("<span title='Issues count'>25 issues</span>")
page_2$get_by_title("Issues count")$highlight()$then()
hover
Hover over the matching element.
inner_h_t_m_l
Returns the element.innerHTML.
inner_text
Returns the element.innerText.
input_value
Returns the value for the matching <input>
or <textarea>
or <select>
element.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text" value="Test"></input>')
input_value <- page_2$get_by_role("text")$first()$input_value(list(timeout=100))$then()
is_checked
Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="checkbox"></input>')
is_checked <- page_2$get_by_role("checkbox")$is_checked(list(timeout=100))$then()
is_disabled
Returns whether the element is disabled, the opposite of enabled.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_disabled <- page_2$get_by_test_id("directions")$is_disabled(list(timeout=100))$then()
is_editable
Returns whether the element is editable.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="checkbox"></input>')
is_editable <- page_2$get_by_role("checkbox")$is_editable(list(timeout=100))$then()
is_enabled
Returns whether the element is enabled.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_enabled <- page_2$get_by_test_id("directions")$is_enabled(list(timeout=100))$then()
is_hidden
Returns whether the element is hidden, the opposite of visible.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_hidden <- page_2$get_by_test_id("directions")$is_hidden(list(timeout=100))$then()
is_visible
Returns whether the element is visible.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_visible <- page_2$get_by_test_id("directions")$is_visible(list(timeout=100))$then()
locator
The method finds an element matching the specified selector in the locator’s subtree. It also accepts filter options, similar to locator.filter() method.
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
locator_inner_text <- page_2$locator('[data-testid="directions"]')$inner_text(list(timeout=100))$then()
nth
Returns locator to the n-th matching element. It’s zero based, nth(0) selects the first element.
nth_inner_text <- page$get_by_role("link")$nth(2)$inner_text(list(timeout=100))$then()
or
Creates a locator that matches either of the two locators.
or_unimplemented <- page$get_by_role("link")$or()
press
Focuses the matching element and presses a combination of the keys.
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text" value="Test"></input>')
page_2$locator("input")$press("Backspace", list(timeout=100))$then()
press_sequentially
Focuses the element, and then sends a keydown, keypress/input, and keyup event for each character in the text.
To press a special key, like Control or ArrowDown, use locator.press().
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text"></input>')
page_2$locator("input")$press_sequentially("World", list(delay=100))$then()
screenshot
Take a screenshot of the element matching the locator.
locator_screenshot <- page$get_by_role("link")$first()$screenshot()$then()
scroll_into_view_if_needed
This method waits for actionability checks, then tries to scroll element into view, unless it is completely visible as defined by IntersectionObserver’s ratio.
See scrolling for alternative ways to scroll.
page$get_by_role("link")$last()$scroll_into_view_if_needed(list(delay=100))$then()
select_option
Selects option or options in <select>
.
page_2 <- context$new_page()$then()
page_2$set_content('<select multiple>
<option value="red">Red</div>
<option value="green">Green</div>
<option value="blue">Blue</div>
</select>')
select_option <- page_2$locator("select")$select_option("blue", list(delay=100))$then()
select_text
This method waits for actionability checks, then focuses the element and selects all its text content.
If the element is inside the
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
page_2$locator("label")$select_text("label", list(delay=100))$then()
set_checked
Set the state of a checkbox or a radio element.
tap
Perform a tap gesture on the element matching the locator.
page$get_by_role("link", list(name="Get started"))$tap()
text_content
Returns the node.textContent.
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
text_content = page_2$locator("label")$text_content(list(delay=100))$then()
uncheck
Ensure that checkbox or radio element is unchecked.
wait_for
Returns when element specified by locator satisfies the state option.
If target element already satisfies the condition, the method returns immediately. Otherwise, waits for up to timeout milliseconds until the condition is met.
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
page_2$locator("label")$wait_for(list(state="visible", timeout=100))$then()
Request
Whenever the page sends a request for a network resource the following sequence of events are emitted by Page:
- page.on(‘request’) emitted when the request is issued by the page.
- page.on(‘response’) emitted when/if the response status and headers are received for the request.
- page.on(‘requestfinished’) emitted when the response body is downloaded and the request is complete.
If request fails at some point, then instead of ‘requestfinished’ event (and possibly instead of ‘response’ event), the page.on(‘requestfailed’) event is emitted.
req_promise <- page$wait_for_event('requestfinished');
page$goto("https://hp-api.onrender.com/api/characters")$then()
req <- req_promise$then()
all_headers
An object with all the request HTTP headers associated with this request. The header names are lower-cased.
req_all_headers <- req$all_headers()$then()
failure
The method returns null unless this request has failed, as reported by requestfailed event.
req_failure <- req$failure()
header_value
Returns the value of the header matching the name. The name is case-insensitive.
req_headers_accept <- req$header_value("accept")$then()
headers
An object with the request HTTP headers. The header names are lower-cased. Note that this method does not return security-related headers, including cookie-related ones. You can use request.allHeaders() for complete list of headers that include cookie information.
req_headers <- req$headers()
headers_array
An array with all the request HTTP headers associated with this request. Unlike request.allHeaders(), header names are NOT lower-cased. Headers with multiple entries, such as Set-Cookie, appear in the array multiple times.
req_headers_array <- req$headers_array()
is_navigation_request
Whether this request is driving frame’s navigation.
Some navigation requests are issued before the corresponding frame is created, and therefore do not have request.frame() available.
req_is_navigation_request <- req$is_navigation_request()
post_data_buffer
Request’s post body in a binary form, if any.
req_post_data_buffer <- req$post_data_buffer()
post_data_j_s_o_n
Returns parsed request’s body for form-urlencoded and JSON as a fallback if any.
When the response is application/x-www-form-urlencoded then a key/value object of the values will be returned. Otherwise it will be parsed as JSON.
req_post_data_j_s_o_n <- req$post_data_j_s_o_n()
redirected_from
Request that was redirected by the server to this one, if any.
When the server responds with a redirect, Playwright creates a new Request object. The two requests are connected by redirectedFrom() and redirectedTo() methods. When multiple server redirects has happened, it is possible to construct the whole redirect chain by repeatedly calling redirectedFrom().
req_redirected_from <- req$redirected_from()
redirected_to
New request issued by the browser if the server responded with redirect.
req_redirected_to <- req$redirected_to()
resource_type
Contains the request’s resource type as it was perceived by the rendering engine. ResourceType will be one of the following: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other.
req_resource_type <- req$resource_type()
response
Returns the matching Response object, or null if the response was not received due to error.
req_response <- req$response()$then()
req_response$ok()
service_worker
The Service Worker that is performing the request.
req_service_worker <- req$service_worker()
timing
Returns resource timing information for given request. Most of the timing values become available upon the response, responseEnd becomes available when request finishes. Find more information at Resource Timing API.
req_timing <- req$timing()
Response
Response class represents responses which are received by page.
page <- context$new_page()$then()
resp <- page$goto("https://hp-api.onrender.com/api/characters")$then()
all_headers
An object with all the response HTTP headers associated with this response.
all_headers <- resp$all_headers()$then()
from_service_worker
Indicates whether this Response was fulfilled by a Service Worker’s Fetch Handler (i.e. via FetchEvent.respondWith).
from_service_worker <- resp$from_service_worker()
header_value
Returns the value of the header matching the name. The name is case-insensitive. If multiple headers have the same name (except set-cookie), they are returned as a list separated by , . For set-cookie, the separator is used. If no headers are found, null is returned.
header_value <- resp$header_value()
header_values
Returns all values of the headers matching the name, for example set-cookie. The name is case-insensitive.
header_values <- resp$header_values()
headers
An object with the response HTTP headers. The header names are lower-cased. Note that this method does not return security-related headers, including cookie-related ones. You can use response.allHeaders() for complete list of headers that include cookie information.
headers <- resp$headers()
headers_array
An array with all the request HTTP headers associated with this response. Unlike response.allHeaders(), header names are NOT lower-cased. Headers with multiple entries, such as Set-Cookie, appear in the array multiple times.
headers_array <- resp$headers_array()$then()
json
Returns the JSON representation of response body. This method will throw if the response body is not parsable via JSON.parse.
json <- resp$json()$then()
ok
Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
ok <- resp$ok()
security_details
Returns SSL and other security information.
security_details <- resp$security_details()$then()
status_text
Contains the status text of the response (e.g. usually an “OK” for a success).
status_text <- resp$status_text()
Frame
At every point of time, page exposes its current frame tree via the page.mainFrame() and frame.childFrames() methods.
Frame object’s lifecycle is controlled by three events, dispatched on the page object:
page.on(‘frameattached’) - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
page.on(‘framenavigated’) - fired when the frame commits navigation to a different URL.
page.on(‘framedetached’) - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
add_script_tag
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.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
child_frame <- child_frames[[1]]
child_frame$add_script_tag(list(content="document.querySelector('[name=mytext1]').value = 'value from add_script_tag'"))$then()
add_style_tag
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.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
child_frame <- child_frames[[1]]
child_frame$add_style_tag(list(content="body { background-color: red }"))$then()
child_frames
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
child_frame_content <- child_frames[[1]]$content()$then()
content
Gets the full HTML contents of the frame, including the doctype.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
child_frame_content <- child_frames[[1]]$content()$then()
drag_and_drop
page$drag_and_drop("#source", "#target")$then()
evaluate
Returns the return value of pageFunction.
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.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
evaluate_result <- child_frames[[1]]$evaluate("([a, b]) => a * b", c(5, 7))$then()
evaluate_handle
Returns the return value of pageFunction as a JSHandle.
The only difference between frame.evaluate() and frame.evaluateHandle() is that frame.evaluateHandle() returns JSHandle.
If the function, passed to the frame.evaluateHandle(), returns a Promise, then frame.evaluateHandle() would wait for the promise to resolve and return its value.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
child_frames[[1]]$evaluate_handle()$then()
frame_element
Returns the frame or iframe element handle which corresponds to this frame.
This is an inverse of elementHandle.contentFrame(). Note that returned handle actually belongs to the parent frame.
This method throws an error if the frame has been detached before frameElement() returns.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
main_frame <- page$main_frame()
child_frames <- main_frame$child_frames()
frame_element <- child_frames[[1]]$frame_element()
frame_locator
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in that iframe.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_text("Berikutnya")$click()$then()
get_by_alt_text
Allows locating elements by their alt text.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_alt_text("Berikutnya")$click()$then()
get_by_label
Allows locating input elements by the text of the associated
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_label("Berikutnya")$click()$then()
get_by_placeholder
Allows locating input elements by the placeholder text.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_placeholder("Berikutnya")$click()$then()
get_by_role
Allows locating elements by their ARIA role, ARIA attributes and accessible name.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_role("Berikutnya")$click()$then()
get_by_test_id
Locate element by the test id.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_test_id("Berikutnya")$click()$then()
get_by_text
Allows locating elements that contain given text.
See also locator.filter() that allows to match by another criteria, like an accessible role, and then filter by the text content.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_text("Berikutnya")$click()$then()
get_by_title
Allows locating elements by their title attribute.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
frame3 <- page$main_frame()$frame_locator("[url=https://ui.vision/demo/webtest/frames/frame_3.html]")
frame3$get_by_title("Berikutnya")$click()$then()
goto
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
The method will throw an error if:
- there’s an SSL error (e.g. in case of self-signed certificates).
- target URL is invalid.
- the timeout is exceeded during navigation.
- the remote server does not respond or is unreachable.
- the main resource failed to load.
- The method will not throw an error when any valid HTTP status code is returned by the remote server, including 404 “Not Found” and 500 “Internal Server Error”. The status code for such responses can be retrieved by calling response.status().
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$goto("https://ui.vision/demo/webtest/frames/")
is_detached
Returns true if the frame has been detached, or false otherwise.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$is_detached()
is_enabled
Returns whether the element is enabled.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$is_enabled("[name=mytext3]", list(timeout=200))$then()
locator
The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to the element immediately before performing an action, so a series of actions on the same locator can in fact be performed on different DOM elements. That would happen if the DOM structure between those actions has changed.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$locator("[name=mytext3]")$focus()$then()
name
Returns frame’s name attribute as specified in the tag.
If the name is empty, returns the id attribute instead.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$name()
page
Returns the page containing this frame.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_page_content <- child_frames[[3]]$page()$content()$then()
parent_frame
Parent frame, if any. Detached frames and main frames return null.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_parent_frame <- child_frames[[3]]$parent_frame()
set_content
This method internally calls document.write(), inheriting all its specific characteristics and behaviors.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
child_frames[[3]]$set_content("content from set_content")
title
Returns the page title.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_title <- child_frames[[3]]$title()$then()
url
Returns frame’s url.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_url <- child_frames[[3]]$url()
wait_for_function
Returns when the pageFunction returns a truthy value, returns that value.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_3 <- child_frames[[3]]
fn_promise <- frame_3$wait_for_function("() => window.innerWidth < 100")
page$set_viewport_size(list(width=50, height=50))$then()
js <- fn_promise$then()
wait_for_load_state
Waits for the required load state to be reached.
This returns when the frame reaches a required load state, load by default. The navigation must have been committed when this method is called. If current document has already reached the required state, resolves immediately.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_3 <- child_frames[[3]]
ev_promise <- frame_3$wait_for_load_state("load")
frame_3$goto("https://playwright.dev/")$then()
ev <- ev_promise$then()
wait_for_u_r_l
Waits for the frame to navigate to the given URL.
page$goto("https://ui.vision/demo/webtest/frames/")$then()
child_frames <- page$main_frame()$child_frames()
frame_3 <- child_frames[[3]]
resp_promise <- frame_3$wait_for_u_r_l("https://playwright.dev/")
frame_3$goto("https://playwright.dev/")$then()
resp_promise$then()
Full Usage Example
devtools::load_all()
roxygen2::roxygenise()
rplaywright::install_rplaywright(force = TRUE)
chrome <- rplaywright::new_chromium()
firefox <- rplaywright::new_firefox()
webkit <- rplaywright::new_webkit()
context <- chrome$new_context()$then()
page <- context$new_page()$then()
resp <- page$goto("https://playwright.dev/")$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-all}
all_links <- page$get_by_role("link")$all()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-all-inner-texts}
all_inner_texts <- page$get_by_role("link")$all_inner_texts()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-all-text-contents}
all_text_contents <- page$get_by_role("link")$all_text_contents()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-and}
and_unimplemented <- page$get_by_role("link")$and()
# @link{https://playwright.dev/docs/api/class-locator#locator-blur}
page$get_by_role("link", list(name="Get started"))$blur()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-bounding-box}
bounding_box <- page$get_by_role("link", list(name="Get started"))$bounding_box()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-check}
page$get_by_role("checkbox")$check(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-clear}
page$get_by_role("textbox")$clear(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-click}
page$get_by_role("link", list(name="Get started"))$click(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-content-frame}
content_frame_unimplemented <- page$get_by_role("link")$content_frame()
# @link{https://playwright.dev/docs/api/class-locator#locator-count}
count <- page$get_by_role("link")$count()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-dblclick}
page$get_by_role("link", list(name="Get started"))$dblclick(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-dispatch-event}
page$get_by_role("link", list(name="Get started"))$dispatch_event('click', NULL, list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-drag-to}
drag_to_unimplemented <- page$get_by_role("link")$drag_to()
# @link{https://playwright.dev/docs/api/class-locator#locator-evaluate}
evaluate_unimplemented <- page$get_by_role("link")$evaluate()
# @link{https://playwright.dev/docs/api/class-locator#locator-evaluate-all}
evaluate_all_unimplemented <- page$get_by_role("link")$evaluate_all()
# @link{https://playwright.dev/docs/api/class-locator#locator-evaluate-handle}
evaluate_handle_unimplemented <- page$get_by_role("link")$evaluate_handle()
# @link{https://playwright.dev/docs/api/class-locator#locator-fill}
page$get_by_role("textbox")$fill("example value", list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-filter}
filter_unimplemented <- page$get_by_role("link")$filter()
# @link{https://playwright.dev/docs/api/class-locator#locator-first}
first <- page$get_by_role("link")$first()
# @link{https://playwright.dev/docs/api/class-locator#locator-focus}
page$get_by_role("link")$first()$focus()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-frame-locator}
frame_locator_unimplemented <- page$get_by_role("link")$frame_locator()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-attribute}
attribute <- page$get_by_role("link")$first()$get_attribute("title")$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-alt-text}
page_2 <- context$new_page()$then()
page_2$set_content("<img alt='Playwright logo'>")
page_2$get_by_alt_text("link")$click(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-label}
page_2 <- context$new_page()$then()
page_2$set_content('<input aria-label="Username"></input>
<label for="password-input">Password:</label>
<input id="password-input"></input>')
page_2$get_by_label("Username")$fill("John", list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-placeholder}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="email" placeholder="name@example.com"></input>')
page_2$get_by_placeholder("name@example.com")$fill("playwright@microsoft.com", list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-role}
page_2 <- context$new_page()$then()
page_2$set_content('<h3>Sign up</h3>
<label>
<input type="checkbox"></input> Subscribe
</label>
<br/>
<button>Submit</button>')
page_2$get_by_role("checkbox", list(name="Subscribe"))$check(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-test-id}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
page_2$get_by_test_id("directions")$click(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-text}
page_2 <- context$new_page()$then()
page_2$set_content('<div>Hello <span>world</span></div>
<div>Hello</div>')
page_2$get_by_text("Hello", list(exact=FALSE))$click(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-get-by-title}
page_2 <- context$new_page()$then()
page_2$set_content("<span title='Issues count'>25 issues</span>")
get_by_title <- page_2$get_by_title("Issues count")$text_content()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-highlight}
page_2 <- context$new_page()$then()
page_2$set_content("<span title='Issues count'>25 issues</span>")
page_2$get_by_title("Issues count")$highlight()$then()
#
page$goto("https://playwright.dev/")$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-hover}
page$get_by_role("link", list(name="Get started"))$hover(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-inner-html}
inner_html = page$get_by_role("link", list(name="Get started"))$inner_h_t_m_l(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-inner-text}
inner_text = page$get_by_role("link", list(name="Get started"))$inner_text(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-input-value}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text" value="Test"></input>')
input_value <- page_2$get_by_role("text")$first()$input_value(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-checked}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="checkbox"></input>')
is_checked <- page_2$get_by_role("checkbox")$is_checked(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-disabled}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_disabled <- page_2$get_by_test_id("directions")$is_disabled(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-editable}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="checkbox"></input>')
is_editable <- page_2$get_by_role("checkbox")$is_editable(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-enabled}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_enabled <- page_2$get_by_test_id("directions")$is_enabled(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-hidden}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_hidden <- page_2$get_by_test_id("directions")$is_hidden(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-is-visible}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
is_visible <- page_2$get_by_test_id("directions")$is_visible(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-last}
last <- page$get_by_role("link")$last()
# @link{https://playwright.dev/docs/api/class-locator#locator-locator}
page_2 <- context$new_page()$then()
page_2$set_content('<button data-testid="directions">Itinéraire</button>')
locator_inner_text <- page_2$locator('[data-testid="directions"]')$inner_text(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-nth}
nth_inner_text <- page$get_by_role("link")$nth(2)$inner_text(list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-or}
or_unimplemented <- page$get_by_role("link")$or()
# @link{https://playwright.dev/docs/api/class-locator#locator-page}
locator_page <- page$get_by_role("link")$page()
# @link{https://playwright.dev/docs/api/class-locator#locator-press}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text" value="Test"></input>')
page_2$locator("input")$press("Backspace", list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-press-sequentially}
page_2 <- context$new_page()$then()
page_2$set_content('<input type="text"></input>')
page_2$locator("input")$press_sequentially("World", list(delay=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-screenshot}
locator_screenshot <- page$get_by_role("link")$first()$screenshot()$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-screenshot}
page$get_by_role("link")$last()$scroll_into_view_if_needed(list(delay=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-select-option}
page_2 <- context$new_page()$then()
page_2$set_content('<select multiple>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>')
select_option <- page_2$locator("select")$select_option("blue", list(delay=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-select-text}
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
page_2$locator("label")$select_text("label", list(delay=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-set-checked}
page_2 <- context$new_page()$then()
page_2$set_content('<h3>Sign up</h3>
<label>
<input type="checkbox"></input> Subscribe
</label>
<br/>
<button>Submit</button>')
page_2$get_by_role("checkbox", list(name="Subscribe"))$set_checked(TRUE, list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-tap}
page$get_by_role("link", list(name="Get started"))$tap()
# @link{https://playwright.dev/docs/api/class-locator#locator-text-content}
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
text_content = page_2$locator("label")$text_content(list(delay=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-uncheck}
page_2 <- context$new_page()$then()
page_2$set_content('<h3>Sign up</h3>
<label>
<input type="checkbox" checked="checked"></input> Subscribe
</label>
<br/>
<button>Submit</button>')
page_2$get_by_role("checkbox", list(name="Subscribe"))$uncheck(TRUE, list(timeout=100))$then()
# @link{https://playwright.dev/docs/api/class-locator#locator-wait-for}
page_2 <- context$new_page()$then()
page_2$set_content('<label>This is a label</label>')
page_2$locator("label")$wait_for(list(state="visible", timeout=100))$then()
chrome$close()$then()
rplaywright::stop_server()
Use Case Example for Twitter Crawling
chrome <- rplaywright::new_chromium()
context <- chrome$new_context(list(
screen = list(width = 1240, height = 1080),
storage_state = list(
cookies = list(
list(
name = "auth_token",
value = "auth_token_from_cookies", # Use auth_token from cookies
domain = ".x.com",
path = "/",
expires = -1,
http_only = T,
secure = T,
same_site = "Strict"
)
),
origins = list()
)
))$then()
page <- context$new_page()$then()
resp <- page$goto("https://x.com/search-advanced")$then()
aresp <- page$wait_for_response(
"resp => (resp.url().includes('SearchTimeline') || resp.url().includes('TweetDetail')) && resp.status() === 200",
list(timeout=15000000)
)
page$get_by_label("All of these words")$fill("playwright")$then()
page$get_by_role("button", list(name="Search"))$click()$then()
resp <- aresp$then()
result <- list()
count <- 1
all_headers = resp$all_headers()$then()
body = resp$body()$then()
finished = resp$finished()$then()
headers = resp$headers()
headers_array = resp$headers_array()$then()
json = resp$json()$then()
ok = resp$ok()
security_details = resp$security_details()$then()
server_addr = resp$server_addr()$then()
status = resp$status()
status_text = resp$status_text()
text = resp$text()$then()
url = resp$url()
frame = resp$frame()
from_service_worker = resp$from_service_worker()
header_value = resp$header_value()
header_values = resp$header_values()
request = resp$request()
result[[count]] <- json
count <- count + 1
while (T) {
print(paste0("Iteration ", count))
page$evaluate("
() => window.scrollTo({
behavior: 'smooth',
top: 0,
})
")$then()
page$evaluate("
async () => await new Promise((r, j) => setTimeout(() => r(), 2000))
")$then()
page$evaluate("
() => window.scrollTo({
behavior: 'smooth',
top: document.body.scrollHeight,
})
")$then()
resp <- aresp$then()
if (is.null(resp)) next;
json = resp$json()$then()
result[[count]] <- json
count <- count + 1
if (count > 3) break;
}
chrome$close()$then()
rplaywright::stop_server()