This patch adds support for `technology preview` webkit channel, which
we will keep close to the actual Safari Technology Preview releases.
This channel does not install by default. It is supposed to be installed
with the following CLI command:
```sh
$ npx playwright install webkit-technology-preview
```
Once the channel is installed, it can be used the following way:
```js
const browser = await playwright.webkit.launch({
channel: 'technology-preview',
});
```
**NOTE:** if clients attempt using the channel without installing it,
it'll throw an error with a copyable instructions to install via CLI.
References #5884
These methods are safe to call while the page is still open, or when it is
already closed. Works in remotely connected browser as well.
Also makes video.path() to throw for remotely connected browser.
Under the hood migrated Download and Video to use the common Artifact object.
There are two problems, exposed by existing tests:
- We do not send Page.startScreeencast before Runtime.runIfWaitingForDebugger
because we launch video recorder in between. This stalls when the page is busy
immediately after resuming, e.g. with alert().
Fixed by starting video recorder in advance.
- We wait for the first frame that may not come - for example, context-wide interception
is blocking essential resource and first frame.
Fixed by only waiting for the first frame before reporting the video, not the page.
For some reason typescript can't find electron types when using
nested tsconfig - workaround the bug.
Drive-by: surface installer compilation problems.
Browser registry is responsible for 3 things:
1. Remove downloaded browsers if there are no packages that refer to them
2. Install default browsers needed for the current package
3. Install browsers on-demand when used through Playwright CLI
Currently, registry relies on a single "download" field in `browsers.json`
to carry both (1) and (2). However, browsers in (3) are marked as
`download: false` so that they aren't installed automatically in (2), so
auto-remove procedure in (1) removes them on subsequent installation.
One possible approach to fix this would be modifying package's `browsers.json` to
change `download: false` to `true` when browsers are installed with
Playwright CLI. This approach was explored here:
bc04a51800
We decided against this since we have a history of issues related to
package modifications after NPM installation. This breaks all
sorts of yarn/npm caching mechanisms.
Instead, this patch is a two-step refactor:
- remove the "download" field in `browsers.json`. Now, all registries
(including old ones from previously-released versions) will retain any
browsers that are mentioned in the `browsers.json`.
- add a new flag "installByDefault", that is **only used** for default
installation.
With this change, the registry tasks are done like this:
- (1) auto-removal: if browser has a back reference, it is retained,
otherwise it is removed from registry
- (2) default installation: use only `installByDefault` to carry default installations
- (3) CLI installation: simply installs browsers. Since we retain
everythings that's referenced in (1), browsers aren't removed.
Fixes#5902
This patch rolls Firefox to r1237. Upstream firefox still struggles
with crashes with certain videos: https://bugzilla.mozilla.org/show_bug.cgi?id=1697004
This PR also workarounds this crash by disabling webrender.
References #5721
This change turns quoted match to be case-sensitive (as before),
but not strictly full-string for the whole element's text.
This is a fix for a case where element contains text nodes and child elements:
```html
<div>text1<span>child node</span>text2</div>
```
We now match this div by `text="text1"` and `text="text2"`.
Cookies have a "Secure" attribute which tells the browsers
that a given cookie should only be sent via HTTPS. In it's
absense "Secure" is falsy and these cookies should be sent
with both HTTP and HTTPS requests. Playwright now returns
only the "Non-Secure" cookies for HTTP URLs, and both
"Secure" and "Non-Secure" cookies for HTTPS URLs.
Fixes#5504
- List all actions we are interested in
- Fix timeline hover flicker
- Extract tabbed pane component
- Preview snapshots without clicking on the action
We might not ever get the "download finished" event when closing the context:
- in Chromium, for any ongoing download;
- in all browsers, for failed downloads.
This should not prevent closing the context. Instead of waiting for the
download and then deleting it, we force delete it immediately and reject
any promises waiting for the download completion.
We get relative registry path when PLAYWRIGHT_BROWSERS_PATH or HOME is relative.
In this case, it would be good to resolve to the same absolute path
during installation and execution, and we can usually do that using INIT_CWD.
- Introduce internal "out of process" start()/stop() mode.
- This mode is used both in regular tests and installation tests.
- Emulate basic driver installation, browser download and running.
- Remove label retargeting, as it does not play nicely with recorder.
- nth-match() is now correctly chained.
- Performance improvements around parent selectors and regex text matches.
- Do not check children when parent does not contain the text we look for.
- Minor caching improvements in evaluator.
This gives up to 5X performance boost on text-heavy pages.
- Snap to buttons, inputs, selects, etc.
- Try `<label>` selector in addition to the element.
- Use parent selectors when needed.
- Remove xpath fallback as it should be covered with css.
Consider the following situation (one among many possible).
- FrameA has an oopif child FrameB;
- FrameA navigates to same-process origin (e.g. about:blank);
- at the same time, FrameC is attached to the FrameB in the
FrameB's process.
In this case, we get `frameNavigated` event for FrameA, immediately
followed by `frameAttached` event for FrameC. Since we detach all
FrameA's child frames on navigation, including the oopif FrameB,
there is no parent frame for FrameC to attach to.
In general, multiple processes coming from oopif may send their
events in wildly different order, and their view about the frame
tree may not always correspond to the "up to date" frame tree as
seen from the main frame's process. We try to keep our frame tree
aligned with what main process thinks, and ignore events that
reference frames absent in this tree.
Drive-by: handle filechooser exceptions because of async processing.
This changes `text=` and `:text()` selectors to match the element when:
- it's combined text content matches the text;
- combined text content of any immediate child does not match the text.
This allows the following markup to match "Some bold and italics text":
`<div>Some <b>bold</b> and <i>italics</i> text</div>`.
For the reference, "combined text content" is almost equal to `element.textContent`,
but with some changes like using value of `<input type=button>` or ignoring `<head>`.
This also includes some caching optimizations, meaningful in complex matches
that involve multiple calls to the text engine.
Performance changes (measured on large page with ~25000 elements):
- `:has-text()` - 14% faster.
- `text=` - 50% faster.
- `:text()` - 0-35% slower.
- `:text-matches()` - 28% slower.
This makes dialogs disappear and prevents stalling.
Pros:
- No need to worry about dialogs for most users.
- Those that wait for a specific dialog still get to control it.
Cons:
- Those who use Playwright to show interactive browser will have
to add an empty 'dialog' handler to prevent auto-dismiss.
We do this in cli.
This patch starts downloading FFMPEG like we download our browsers
instead of bundling it in the NPM package.
With this patch, NPM size is reduced from 8.8MB to 1.7MB.
Consequences:
- `npx playwright` is drastically faster now
- playwright driver for language bindings is way smaller
- projects that bundle Playwright can pass Apple Notorization
Fixes#5193
- We don't need this, since it should propagate from the main frame.
- Forcing focus in oopif immediately focuses it and blurs currently
focused frame. This leads to undesired side effects, e.g. selects
being closed.
This switches vp8 to "realtime" mode that works fast, adapting to
the speed of incoming frames, and produces the best quality in can
given realtime constraints.
In practice, this gives 2x larger video files but no noticible quality
difference. It also eliminates huge delays for encoding the video.
Drive-by: document our ffmpeg option choices and add some links
to documentation for future use.
This fix restores the ability to display images in the Network Tab inside Trace Viewer. Previously data returned from the server was coming back as base64 encoded string, but now it is returned as a Buffer object. This required convertion to either base64 encoded string or utf8 encoded string on the frontend.
Co-authored-by: Dominik Deren <dominik.deren@live.com>
Everything but attributes in the light dom is manually compared during
DOM traversal, for example child nodes or scroll offset.
This way we get a bullet-proof solution that works with input values,
scroll offsets, shadow dom and anything else web comes up with.
We also restore scroll only on the document scrolling element, for
performance reasons. We should figure out the story around scrolling.
Changes stationary snapshots from ~0.5ms to ~2.5ms due to DOM traversal.
- Intercept CSSOM modifications and recalculate overridden css text.
- When css text does not change, use "backwards reference" similar
to node references.
- Set 'Cache-Control: no-cache' for resources that could be overridden.
- Switch from html to json ml format.
- Allow node reuse between snapshots with `[nSnapshotsBefore, nodeWithIndexM]`.
- Service worker now lazily serializes snapshot chunks into a single html.
This decreases total snapshot size on random scripts ~10x.
This also decreases snapshot collecting time on mostly static pages to ~0.3ms.
Unfortunate downside for now is that we have to intercept
`Element.prototype.attachShadow` to invalidate nodes. This
also temporary breaks scroll restoration. Needs more research.
- Move service worker under /snapshot/ instead of /.
- Fix stylesheet base uri bug, where we inherited the wrong base url.
- Introduce TraceServer and routes there, split the actual routes
between snapshot, ui and action previews.
This change is adding a new property on the BrowserContextOptions class called `_debugName`. This property allows defining a user-friendly name for the browser context, and currently it is being used in one place, the Trace Viewer. When user provides the new value in the following way:
```typescript
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({ _traceDir: __dirname, _debugName: 'My custom testcase name' });
await context.close();
await browser.close();
})();
```
The `_debugName` will be saved in the `*.trace` file for this browser context, on the `context-created` event, under the key `debugName`.
Later, when such a trace is displayed using Trace Viewer, the `debugName` will be displayed in the dropdown in the top right part of the app instead of the actual trace filename.
Fixes#5157.
Installer has a code to download browsers from the old version of
playwright. This, however, is never needed, since installer only
installs browsers from its own version.
This introduces an http server that serves our frontend and our snapshots. There is more work to untangle the big server into a few modules.
This change allows us:
- Maybe eventually serve the trace viewer as a web page.
- Rely on browser caches for fast snapshot rendering. This PR also adds "snapshot on hover" feature, subject to change.
feat(trace viewer): Extending existing NetworkTab view
Currently the network tab contains a limited amount of information on the resources that were loaded in the browser. This change proposes extending the details displayed for each resource, to include:
- HTTP method,
- Full url,
- Easily visible response content type,
- Request headers,
- Request & response bodies.
Such level of information could help quickly understand what happened in the application, when it was communicating with backend services. This can help debug tests quicker to figure out why they are failing.
This implementation still needs some clean up & tests improvement, but I wanted to propose such changes and gather your feedback before going too far.
- Instead of capturing snapshots on demand, we now stream them
from each frame every 100ms.
- Certain actions can also force snapshots at particular moment using
"checkpoints".
- Trace viewer is able to show the page snapshot at a particular
timestamp, or using a "checkpoint" snapshot.
- Small optimization to not process stylesheets if CSSOM was not used.
There still is a lot of room for improvement.
When `page.reload()` is racing against the renderer-initiated
navigation, we might end up with `waitForNavigation()` being rejected
before the reload implementation is able to catch it.
To avoid that, carefully use Promise.all and await `waitForNavigation`
from the get go.
Same happens to `page.goForward()` and `page.goBack()`.
This changes quoted text selector like `text="Foo Bar"` to perform
normalized whitespace match.
Most of the time users want to match some string visible on the page,
and that always means normalized whitespace.
We keep the case sensitivity and full-string vs substring difference
between quoted and unquoted matches.
Pre-BigSur, MacOS updates were labeled as "minor" releases, so we had
to bake separate builds for different 10.X releases.
In BigSur era, it doesn't seem to be the case, so for now we can re-use
our BigSur builds across all BigSur versions (11.0, 11.1 and 11.2).
If we ever need to have a custom build for some bigsur minor version,
e.g. `11.6`, we'll have a new browser platform along with generic
`mac11` platform.
Fixes#4775.
fix(trace viewer): updating default traceStorageDir value
When `npx playwright show-trace <tracePath>` command is executed, without providing the `resources` optional parameter, the function expected the `traceStorageDir` default value to be the same directory as in which the tracePath resides. This change updates it to the `dirname(tracePath)/trace-resources` if it exists. Such a directory hirerachy is the default that is created when running the tracer in Playwright.
This adds `{Page,Frame}.isChecked(selector)` and `ElementHandle.isChecked()` methods.
Useful to do assertions in tests:
```js
await page.click('text="Add TODO"');
expect(await page.isChecked('.item-done')).toBe(false);
```
- Allow specifying which browsers to install. This comes handy in playwright-cli.
- Print "npx playwright" as a tool name in help messages, instead of "cli".
These methods are useful for verification in tests, e.g.
```js
expect(await page.isEnabled(':text("Remove All")')).toBe(false);
await page.click(':text("Add Item")');
expect(await page.isVisible('.item:text("new item")')).toBe(true);
expect(await page.isEnabled(':text("Remove All")')).toBe(true);
```
This patch:
- introduces non-exported but used in api/impl struct types (e.g. Point);
- makes all client classes implement respective public api interface.
Pros:
- Typescript is now responsible for type checking.
We can remove our doclint checker (not removed yet).
- Electron and Android types can be defined in the same way
(this is not implemented yet).
- We can move most of the type structs like Point to the public api
and make some of them available.
Cons:
- Any cons?
When element with position:sticky covers some part of
the scroll container, we could fail to scroll from under it
to perform an action. To fight this, we can try different
scroll alignments and scroll to the top/bottom/center
in the attempt to scroll away from sticky header/footer/sidebar.
When the client only closes the input pipe, we are still
sending protocol messages over the output pipe. This could
probably lead to some errors, e.g. write buffer being full.
11.1 is an official update for macOS Big Sur. We should maybe add a custom macOS version parser which falls back if minor version changes so we don't have to maintain all the versions manually.
Fixes#4722
Windows 7 was end-of-lifed on January 14, 2020. We don't support this
system, but we'd like to have a best-effort to work there.
It does look like Chromium is missing some libraries on Win 7, however
it still manages to work there. To support this usecase, this patch
starts printing console warning about missing libraries on Win 7 only
instead of refusing to launch.
Fixes#3496
We now default to `text` that does substring case-insensitive match
with normalized whitespace. `text-is` matches the whole string.
`matches-text` is renamed to `text-matches`.
When parsing CSS, we assume everything is a valid CSS function,
unless it is in the list of custom functions. This way we'll parse
future CSS functions automatically.
PW_TRACE_DIR points to a directory that Playwright can
put trace files and resources into.
This does not enable video recording, although it might
in the future.
When using 'domain' module, it calls various EventEmitter methods
like 'listenerCount' that we do not expect. To avoid this problem
in the future, we validate the method name before sending it over
the protocol connection.
Currently, we always throw from FrameSession._stopScreencast
when not running with video, and immediately catch it in
CRPage.didClose (thanks to debugger to point that).
Overall, we have code prepared for start/stop API, which
we never did, so it makes sense to simplify code a bit,
and throw if something goes wrong.
This fixes the local -> remote frame swap when
Page.frameDetached arrives before Target.attachedToTarget.
Instead of error-prone logic we do currently, new CDP exposes
frame detach reason that we can use.
New webkit build, generated by 19f21b1bde, changed webkit build
layout: now there are subfolders that contain libraries and executables, and some of the dependencies are no longer bundled.
This patch:
- teaches launch doctor new directories structure: subfolders are now inspected for missing dependencies, and they are also used in the `LD_LIBRARY_PATH`.
- adds `libevent` and `libicudata` libs to the mapping for ubuntu 18.04
This enables filling the input based on the connected label:
```html
<label for=target>Name</label><input id=target>
```
```js
await page.fill('text=Name', 'Alice');
```
Consider the following sequence:
- page opens a popup;
- popup target is attached, we start initializing it;
- user calls browser.close();
- browser is closed, and popup initialization fails;
- we report "errored page" on the already closed context;
- RPC client cannot make sense of this:
"Cannot find parent object BrowserContext@guid to create Frame@guid"
This issue was revealed during Firefox pipe migration.
Certain environments, e.g. Azure Pipelines, override default user
inside container with a custom one, whereas fail to pass proper
seccomp profile for the docker image.
As a result, chromium sandboxing fails.
To ease life of devops deploying tests in various CI's, this patch
disables Chromium sandbox by default.
References #4084
There is a race between "close" event coming from the server and
"close" command issued from the client.
This is similar to calling close after disconnect, so added tests.
This saves some CPU cycles while waiting for the page to
change the state, e.g. for animations to complete.
Note that retrying logic is only applicable in rare
circumstances like unexpected scroll in the middle of an
action, or some overlay blocking the click. Usually,
action times out in this cases while retrying.