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.