This PR fixes the following edge case:
- `const oldPromise = world.puppeteerUtil`.
- setContext occurs but context is immediately destroyed, i.e.
`world.#puppeteerUtil === oldPromise` is not resolved.
- clearContext occurs due to destruction, i.e. `world.#puppeteerUtil` is
replaced (`world.#puppeteerUtil !== oldPromise`).
- `oldPromise` never resolves.
<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->
**What kind of change does this PR introduce?**
Test expectation file update
**Did you add tests for your changes?**
no
**Summary**
Unskippes tests for Firefox and linux, which were missed in the previous
update
**Does this PR introduce a breaking change?**
no
Issue: #9394
**What kind of change does this PR introduce?**
Feature - Added support of the `referrerPolicy` parameter (from CDP's
`Page.navigate`) to Puppeteer's `page.goto`.
**Did you add tests for your changes?**
No, currently it has no meaning that isn't browser implementation based,
which might get broken in the future. If there are suggestions to tests,
please let me know so I'll add them.
**If relevant, did you update the documentation?**
Yes, the documentation of the `goto` method has been updated.
**Summary**
I wanted to contribute to this project, which I used for testing on our
environment and saw issue #9394, so I decided to resolve it :)
**Does this PR introduce a breaking change?**
No. I added the `referrerPolicy` as an optional parameter, which will
use the HTTP header `Referrer-Policy` if not provided (much like the
`referer` parameter) so it will not interfere.
Co-authored-by: Ophir Back <ophir.back@broadcom.com>
What kind of change does this PR introduce?
Test expectation file update
Summary
Closes https://github.com/puppeteer/puppeteer/issues/9118.
This PR updates the test expectation file with more specific status for
firefox (like fail, fail-pass), removes the duplications.
Does this PR introduce a breaking change?
no
Bumps [glob](https://github.com/isaacs/node-glob) from 8.0.3 to 8.1.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/isaacs/node-glob/blob/main/changelog.md">glob's
changelog</a>.</em></p>
<blockquote>
<h2>8.1</h2>
<ul>
<li>Add <code>windowsPathsNoEscape</code> option</li>
</ul>
<h2>8.0</h2>
<ul>
<li>Only support node v12 and higher</li>
<li><code>\</code> is now <strong>only</strong> used as an escape
character, and never as a
path separator in glob patterns, so that Windows users have a
way to match against filenames containing literal glob pattern
characters.</li>
<li>Glob pattern paths <strong>must</strong> use forward-slashes as path
separators, since <code>\</code> is an escape character to match literal
glob pattern characters.</li>
<li>(8.0.2) <code>cwd</code> and <code>root</code> will always be
automatically coerced
to use <code>/</code> as path separators on Windows, as they cannot
contain glob patterns anyway, and are often supplied by
<code>path.resolve()</code> and other methods that will use
<code>\</code> path
separators by default.</li>
</ul>
<h2>7.2</h2>
<ul>
<li>Add fs option to allow passing virtual filesystem</li>
</ul>
<h2>7.1</h2>
<ul>
<li>Ignore stat errors that are not <code>ENOENT</code> to work around
Windows issues.</li>
<li>Support using root and absolute options together</li>
<li>Bring back lumpy space princess</li>
<li>force 'en' locale in string sorting</li>
</ul>
<h2>7.0</h2>
<ul>
<li>Raise error if <code>options.cwd</code> is specified, and not a
directory</li>
</ul>
<h2>6.0</h2>
<ul>
<li>Remove comment and negation pattern support</li>
<li>Ignore patterns are always in <code>dot:true</code> mode</li>
</ul>
<h2>5.0</h2>
<ul>
<li>Deprecate comment and negation patterns</li>
<li>Fix regression in <code>mark</code> and <code>nodir</code> options
from making all cache
keys absolute path.</li>
<li>Abort if <code>fs.readdir</code> returns an error that's
unexpected</li>
<li>Don't emit <code>match</code> events for ignored items</li>
<li>Treat ENOTSUP like ENOTDIR in readdir</li>
</ul>
<h2>4.5</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1b6bf20239"><code>1b6bf20</code></a>
8.1.0</li>
<li><a
href="1756fccfe7"><code>1756fcc</code></a>
add windowsPathsNoEscape option</li>
<li><a
href="af57da21c7"><code>af57da2</code></a>
update tap, libtap</li>
<li><a
href="e19db65d23"><code>e19db65</code></a>
Remove dependency on path-is-absolute</li>
<li>See full diff in <a
href="https://github.com/isaacs/node-glob/compare/v8.0.3...v8.1.0">compare
view</a></li>
</ul>
</details>
<br />
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=glob&package-manager=npm_and_yarn&previous-version=8.0.3&new-version=8.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->
**What kind of change does this PR introduce?**
types fix
**Did you add tests for your changes?**
No
**If relevant, did you update the documentation?**
Not relevant
**Summary**
I am updating `import`s of `devtools-protocol` to always use named
import instead of the default.
For some reason, typescript doesn't understand when it is imported as
default.
```
node_modules/puppeteer-core/lib/esm/puppeteer/common/TargetManager.d.ts:23:59 - error TS2694: Namespace '"/Users/kyrylo/pacakge/node_modules/puppeteer-core/node_modules/devtools-protocol/types/protocol"' has no exported member 'Target'.
23 export declare type TargetFactory = (targetInfo: Protocol.Target.TargetInfo, session?: CDPSession) => Target;
~~~~~~
Found 1 error in node_modules/puppeteer-core/lib/esm/puppeteer/common/TargetManager.d.ts:23
```
**Does this PR introduce a breaking change?**
No
<!-- If this PR introduces a breaking change, please describe the impact
and a migration path for existing applications. -->
**Other information**
I am updating `import`s of `devtools-protocol` to always use named
import instead of the default.
<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->
**What kind of change does this PR introduce?**
This is a change to a custom mocha runner to look for expectation of the
test case by the whole test name instead of by the part of the name.
**Summary**
Working on integration of the puppeteer expectation file in mozilla repo
and unskipping a lot of tests, I've noticed that some tests get wrong
statuses. For example, a test case with the name `navigation Page.goto
should fail when navigating to bad SSL` got the status of `navigation
Page.goto should fail when navigating to bad SSL after redirects` or
`ElementHandle specs ElementHandle.boundingBox should work` get the
status of `ElementHandle specs ElementHandle.boundingBox should work
with SVG nodes`. So it seems like checking for the whole name of the
test should be safer, but let me know if I'm missing something here.
**Does this PR introduce a breaking change?**
no
Issue: #1313
<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->
**What kind of change does this PR introduce?**
Feature.
**Did you add tests for your changes?**
Yes.
**If relevant, did you update the documentation?**
Yes.
**Summary**
Supports keyboard shotcuts on MacOS. See Chrome Devtools Protocol
document:
https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent.
<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->
**What kind of change does this PR introduce?**
- adds missing golden asset for firefox
**Summary**
- This change will let us see in mozilla ci, where we don't skip this
test, a better error message. Right now it fails with missing asset
error.
**Does this PR introduce a breaking change?**
no
This PR adds configurations files to `puppeteer`'s methods for
configuration. Under the hood, `puppeteer` relies on
https://www.npmjs.com/package/cosmiconfig which resolves several formats
of configuration:
- a `puppeteer` property in package.json
- a `.puppeteerrc` file in JSON or YAML format
- a `.puppeteerrc.json`, `.puppeteerrc.yaml`, `.puppeteerrc.yml`,
`.puppeteerrc.js`, or `.puppeteerrc.cjs` file
- a `puppeteer.config.js` or `puppeteer.config.cjs` CommonJS module
exporting an object
Documentation will be added later.
Fixed: #9128
This PR removes the deprecated query selector API from the `puppeteer`
instance. Direct imports of the query selector API have also been
deprecated and users are now expected to use the static methods defined
on `Puppeteer`.
This PR removes the deprecated `puppeteer.devices` in favor of a new
exported object `KnownDevices`. `devices` can also be exported, but has
been deprecated.
This PR separates the installations tests from normal tests and changes
the matrices as follows:
- Installations tests on all platforms and the latest 3 node versions.
- Chrome tests are done on all platforms on the latest node version.
- Firefox tests are done only on linux on the latest node version.
This PR moves the puppeteer source code into separate mono-repo packages:
- `puppeteer` and `puppeteer-core` are now separated into their own
packages.
- `puppeteer-core` has a new exports called `puppeteer-core/internal`
for internal usage.
Tests and various tools have been updated to accommodate the migration.
This PR starts the monorepo migrations as per
https://github.com/puppeteer/puppeteer/issues/8922. To scope migrations,
we are only moving the `testserver` into a separate package. Further
migrations will come later.
This PR adds a basic support for WebDriver BiDi that currently includes only the ability to establish a connection and shutdown the browser. Therefore, the implementation is marked as internal and won't show up in the changelog as it's barely useful at the moment.
The API classes are kept as classes instead of interfaces so that clients relying on instanceof checks still work.
Instead of checking skipped tests in mocha-utils this PR
implements a custom mocha interface for better flexibility
when skipping tests. That should allow skipping tests without
running before and after hooks.
* chore: implement a test runner on top of mocha
This PR implements a test runner on top of mocha
that performs multiple mocha runs as defined in
TestSuites.json and compares the outcome of the runs
against TestExpectations.json. This allows us to
remove most of helpers from mocha-utils and be more
flexible when defining the test configurations.
Two main sources of flakiness addressed:
1) we should dispose the lifecycle watcher after we waited for the navigation response (bad API? we need to refactor but I think it'd be valuable to stabilize tests first without too many changes).
2) we should wait for the navigation request's response if there is a navigation request in the watcher.
Closes#8644
Previously, if timeout is falsy, the targets would only
be checked if a browser-level event fires which lead to
a race: if the events arrived before waiting for a target,
the promise would never resolve.
Fixes#8763
This PR implements automatic detection of the Firefox product when the `.connect()` method is used. This partially undoes the breaking change in https://github.com/puppeteer/puppeteer/pull/8520 but it's also a breaking change on its own since we don't accept an explicit product name anymore (it does not look like it was used anyway).
When we attach to a frame, we send a call to get
the page frame tree from CDP. Based on the tree data
we look up the parent frame if parentId is provided.
The problem is that the call to get the page frame
tree could take arbitrary time and the calls for the
parent and child frames might happen at the same time.
So the situation where the frame tree for the child frame
is resolved before the parent frame is known is fairly
common.
This PR addresses the issue by awaiting for the parent
frame id before attempting to register a child frame.
* feat: use CDP's auto-attach mechanism
In this PR, we refactor Puppeteer to make use of the CDP's auto-attach mechanism. This allows the backend to pause
new targets and give Puppeteer a chance to configure them properly. This fixes the flakiness related to dealing with
OOPIFs and should fix some other issues related to the network interception and navigations. If those are not fixed completely by this PR, the PR serves a solid base for fixing them.
Closes https://github.com/puppeteer/puppeteer/issues/8507, https://github.com/puppeteer/puppeteer/issues/7990
Unlocks https://github.com/puppeteer/puppeteer/issues/3667
BREAKING CHANGE: With Chromium, Puppeteer will now attach to page/iframe targets immediately to allow reliable configuration of targets.
This patch fixes page.#scrollIntoViewIfNeeded, so that it works with devtools protocol.
Now it blocks the main thread and waits until the scrolling action finishes in Chrome.
Fallbacks to the old implementation if `DOM.scrollIntoViewIfNeeded` is not supported for Firefox.
Issues: #8627, #1805
This PR greatly improves the types within Puppeteer:
- **Almost everything** is auto-deduced.
- Parameters don't need to be specified in the function. They are deduced from the spread.
- Return types don't need to be specified. They are deduced from the function. (More on this below)
- Selections based on tag names correctly deduce element type, similar to TypeScript's mechanism for `getElementByTagName`.
- [**BREAKING CHANGE**] We've removed the ability to declare return types in type arguments for the following reasons:
1. Setting them will indubitably break auto-deduction.
2. You can just use `as ...` in TypeScript to coerce the correct type (given it makes sense).
- [**BREAKING CHANGE**] `waitFor` is officially gone.
To migrate to these changes, there are only four things you may need to change:
- If you set a return type using the `ReturnType` type parameter, remove it and use `as ...` and `HandleFor` (if necessary).
⛔ `evaluate<ReturnType>(a: number, b: number) => {...}, a, b)`
✅ `(await evaluate(a, b) => {...}, a, b)) as ReturnType`
⛔ `evaluateHandle<ReturnType>(a: number, b: number) => {...}, a, b)`
✅ `(await evaluateHandle(a, b) => {...}, a, b)) as HandleFor<ReturnType>`
- If you set any type parameters in the *parameters* of an evaluation function, remove them.
⛔ `evaluate(a: number, b: number) => {...}, a, b)`
✅ `evaluate(a, b) => {...}, a, b)`
- If you set any type parameters in the method's declaration, remove them.
⛔ `evaluate<(a: number, b: number) => void>((a, b) => {...}, a, b)`
✅ `evaluate(a, b) => {...}, a, b)`
* The testing tsconfig.json inherits from the base TS config.
* A lot of type assertions have been inserted...a lot.
* All testing utilities have migrated to TS.
* text-diff is being replaced with diff for TS compatibility.
* ProtocolError has been added to PuppeteerErrors and PuppeteerErrors is no longer a record (it's been frozen).
* Fixes a small bug where null was an allowable media type in emulation (should be undefined).
* fix: If currentNode and root are the same, do not include them in the result
* fix: Tests that only child element is included in the result
Co-authored-by: jrandolf <101637635+jrandolf@users.noreply.github.com>
* fix: test failing in headful
* fix: install Firefox for headful tests
* fix: skip favicon.ico requests in test
* fix: auth test in headful
* fix: disable NetworkTimeServiceQuerying
* fix: filter more favicon requests
* fix: network test with favicon
* fix: improve fixes
Without this patch, two tests ignore the BINARY envvar, and fail when not using
the embedded chromium, unless the chromium executable path is defined via
PUPPETEER_EXECUTABLE_PATH, which should not be considered according to the
docs.
* fix: ensure dom binding is not called after detatch
Fixes#7814
* refactor: detach listeners instead
* refactor: safer approach
* fix: test in test/page.spec.ts
Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
Some recent changes to allow arm64 environments (including M1 macs) to
launch a chromium installation successfully before arm-compatible builds
were downloadable prevented the usage of PUPPETEER_EXECUTABLE_PATH in
some environments. Currently, when the platform is not darwin and the
arch is arm64, an executable cannot be specified using the environment
variable.
Generally speaking, environment variables have highest precedence for
options such as this since they depend on system configuration.
These change:
1. allow the ENV variable to always be used when defined and not
specified in LaunchOptions (and when not puppeteer-core)
2. Retain the existing behavior of assuming /usr/bin/chromium-browser on
platforms like Ubuntu (exact if-conditions preserved to avoid any
breaking changes)
3. Add some tests for this particular portion of the code.
The doc for boundingBox says that it should return the boundingBox
relative to the main frame, therefore, this fix would make the
actual implementation correspond to the documentation. boxModel
documentation does not have this note but I think it'd make sense
to have it match the behaviour of the boundingBox API.
So it appears that all bindings are added to the secondary world and all
evaluations are also running there. ElementHandle.evaluate is returning
handles from the main world though. Therefore, we need to be careful
and adopt handles to the right context before doing waitForSelector
So it appears that all bindings are added to the secondary world and all
evaluations are also running there. ElementHandle.evaluate is returning
handles from the main world though. Therefore, we need to be careful
and adopt handles to the right context before doing waitForSelector.
When using a custom Firefox profile for Puppeteer the modified
preferences as present in prefs.js need to be reset once the
profile is no longer needed by Puppeteer. If not done this could
cause side-effects when the profile is used next time outside
of Puppeteer.
As ride-along fix the "--foreground" argument for Firefox will
only be used on MacOS because that's the only supported platform.
This updates the regular expression used to parse aria attribute
selectors so that single quotes may be used as an alternative to double
quotes, e.g. `aria/Single button[role='button']`.
Issues: #7721
Co-authored-by: Andy Earnshaw <andy.earnshaw@gmail.com>
This pull request to adds better support for OOP iframes (see #2548)
The current problem with OOP iframes is that they are moved to a different target. Because of this, the previous versions of Puppeteer pretty much ignored them.
This change extends the FrameManager to already take OOP iframes into account and hides the fact that those frames are actually in different targets.
Further work needs to be done to also make the NetworkManager aware of these and to make sure that settings like emulations etc. are also properly passed down to the new targets.
In some situations, Puppeteer is left in an invalid state because protocol errors that could have been handled by the user where just hidden from them. This patch removes some of these cases and also makes sure that unhandled promise rejections lead to a test failure in mocha.
Enable developers to handle 'Invalid header' errors instead of hiding them to make sure they can address them properly.
Co-authored-by: Jan Scheffler <janscheffler@chromium.org>
Sometimes an element has not been layed out yet and, in this case,
clickablePoint fails because backend cannot compute content quads.
Co-authored-by: Jan Scheffler <janscheffler@chromium.org>
Puppeteer already allows creating a new CDP session
via target.createCDPSession but there is no way
to get access to any existing session to send
some additional commands.
Until now, the click would be always sent to the middle
point of the target element. With this change, one can define
offsets relative to the border box of the elements and click
different areas of an element.
Up to now, only strings starting with '//' are considered as to XPath selectors. Unfortunately, this is too restricting. This fix allows valid XPath selectors starting with: '/', './', and even '(//*[1])'
This change adds a new `channel` parameter to `puppeteer.launch`. When specified, Puppeteer will search for the locally installed release channel of Google Chrome and use it to launch. Available values are `chrome`, `chrome-beta`, `chrome-canary`, `chrome-dev`. This parameter is mutually exclusive with `executablePath`.
With this change,`request.respond`, `request.abort`, and `request.continue` can accept an optional `priority` to activate Cooperative Intercept Mode. In Cooperative Mode, all intercept handlers are guaranteed to run and all async handlers are awaited. The interception is resolved to the highest-priority resolution. See _Cooperative Intercept Mode and Legacy Intercept Mode_ in `docs/api.md` for details.
This commit adds drag-and-drop support, leveraging new additions to the CDP Input domain (Input.setInterceptDrags, Input.dispatchDragEvent, and Input.dragIntercepted).
Just some code reorder. We had a describe between it calls. I'm moving that describe to the end
Co-authored-by: Jack Franklin <jacktfranklin@chromium.org>
* chore: enforce pinned dependencies
Because we don't check our `package-lock.json` in, we can end up with
different versions installed locally vs CI, or even two devs having
different versions. Let's pin and enforce we pin every version to
avoid this.
This PR updates some code to remove constant ESLint warnings. It also
upgrades those warnings to errors - so that they have to be resolved
as part of the PR, rather than landing as a warning and causing noise.
Fixes#7229.
We're seeing odd failures with Prettier on some CI branches; my hunch is that they are installing different versions of the package and therefore getting formatting conflicts. This PR updates them all and pins them to specific versions - something we should probably consider generally, or remove our `package-lock.json` from the gitignore.
The existing behavior is expected to be unchanged as the value defaults to true.
Adding such option would allow user to skip the initial wait.
Issue: #3630
* fix: make `$` and `$$` selectors generic
This means, much like TS's in built `querySelector` type, you can now do:
```ts
const listItems = page.$$<HTMLLIElement>('ul li');
```
And/or:
```ts
const h2 = page.$<HTMLHeadingElement>('h2');
```
And the return value will be of type `ElementHandle<T>|null`, where `T`
is the type you provided. By default `T` is an `Element`, so you don't
have to provide this if you don't care as a consumer about the exact
type you get back.
* chore: fix test assertions
* feat(chromium): roll Chromium to r856583
This corresponds to Chromium 90.0.4427.0
This roll includes:
- Add sourceScheme, sourcePort, and sameParty to DevTools backend (https://crbug.com/1170548, https://crbug.com/1142606)
We were blocked on doing this because API Extractor didn't support it,
but now it does, so we can bump TS and the API tooling in one go. None
of the breaking changes in TS4 cause us any issues.
During the migration to TS we changed `jsonValue` so it returned
`<Record<string, unknown>>`. This is only true if all the JSON values it
returns are objects; but it could return an array, a string, a number,
etc. Therefore we make the type generic, setting the default to
`unknown`, so the user has control over the type.
This corresponds to Chromium 90.0.4403.0
This roll includes:
- Cut screenshot by ViewPort size, not position (crrev.com/c/2643792)
BREAKING CHANGE:
- `page.screenshot` cuts screenshot content by the ViewPort size, not ViewPort position.
This corresponds to Chromium 89.0.4389.0.
This roll includes:
- Add `SameParty` attribute to cookies
https://crrev.com/c/2598846
- Anchor `target=_blank` implies `rel=noopener`
https://crrev.com/c/1630010
- Don’t expect ignored elements in the AXTree
https://crrev.com/c/2505362
BREAKING CHANGE: The built-in `aria/` selector query handler doesn’t return ignored elements anymore.
Issue: #6758
This patch enables more tests for Firefox. These tests are enabled in Mozilla's CI for Firefox. The extra error handling here prevents hangs in the test harness in that environment.
The `Puppeteer` class had two concerns:
* connect to an existing browser
* launch a new browser
The first of those concerns is needed in all environments, but the
second is only needed in Node.
https://github.com/puppeteer/puppeteer/pull/6484 landing enabled us to
pull the `Puppeteer` class apart into two:
1. `Puppeteer` which hosts the behaviour for connecting to existing
browsers.
2. `PuppeteerNode`, which extends `Puppeteer` and also adds the ability
to launch a new browser.
This is a non-breaking change, because Node users will still get an
instance of a class with all the methods they expect, but it'll be a
`PuppeteerNode` rather than `Puppeteer`. I don't expect this to cause
people any issues.
We also now have new files that are effectively the entry points for
Puppeteer:
* `node.ts`: the main entry point for Puppeteer on Node.
* `web.ts`: the main entry point for Puppeteer on the web.
* `node-puppeteer-core.ts`: for those using puppeteer-core (which only
exists in Node, not on the web).
Launching headless with a relative `userDataDir` hangs on Windows. Fix by calling `path.resolve` (idempotent) to add an absolute path instead in `defaultArgs`.
Issues: #3453
The `Launcher` class was serving two purposes:
1. Launch browsers
2. Connect to browsers
Number 1) only needs to be done in Node land, but 2) is agnostic; in a
browser version of Puppeteer we'll need the ability to connect over a
websocket to send commands back and forth.
As part of the agnostification work we needed to split the `Launcher` up
so that the connection part can be made agnostic. Additionally, I
removed dependencies on `https`, `http` and `URL` from Node, instead
leaning on fetch (via `node-fetch` if in Node land) and the browser
`URL` API (which was added to Node in Node 10).
This commit adds a new built-in handler for querying by accessible name and role (#6307).
Support for waitForSelector will be added in a follow-up commit.
In `src/common` we now use `fs.promises.X` which we can dynamically
`import`. In a browser environment this code will never run because it's
gated on `isNode` (in a future PR we will add tree-shaking to the bundle
step such that this code is eliminated). By using `import`, we ensure
TypeScript still can track types and give good type information.
In `src/node` we continue to use `util.promisify` but that's not a
concern as that code explicitly is never run in the browser.
This commit changes the internal representation of query handlers to contain Puppeteer-level code instead of page functions.
The interface `CustomQueryHandler` is introduced for user-defined query handlers. When a `CustomQueryHandler` is registered using `registerCustomQueryHandler` a corresponding Puppeteer-level handler is created through `makeQueryHandler` by wrapping the page functions as appropriate.
The internal query handlers (defined by the interface `QueryHandler`) contain two new functions: `waitFor` and `queryAllArray`.
- `waitFor` allows page-based handlers to make use of the `WaitTask`-backed implementation in `DOMWorld`, whereas purely Puppeteer-based handlers can define an alternative approach instead.
- `queryAllArray` is similar to `queryAll` but with a slightly different interface; it returns a `JSHandle` to an array with the results as opposed to an array of `ElementHandle`. It is used by `$$eval`.
After this change, we can introduce built-in query handlers that are not executed in the page context (#6307).
The logic for waitForXPath and waitForSelector is currently very tightly coupled. This commit tries to untangle that relationship. This is the first step towards introducing built-in query handlers that are not executed in the page context (#6307).
This corresponds to Chromium 85.0.4182.0.
This roll includes:
- Enable SameSiteByDefaultCookies and CookiesWithoutSameSiteMustBeSecure
https://crrev.com/c/2231445
- [FlexNG] Enable FlexNG by default
https://crrev.com/c/2216595Closes#6151.
* chore: vendor Mitt into src/common/third-party
As discussed in #6203 we need to vendor our common dependencies in so
that when we ship an ESM build all imports point to file paths and do
not rely on Node resolution (e.g. a browser does not understand `import
mitt from 'mitt'`).
* chore: enforce file extensions on imports
To make our output agnostic it should include file extensions in the
output, as per the ESM spec. It's a bit odd for Node packages but makes
it easier to publish a browser build.
* feat(chromium): roll Chromium to r768783
* fix: update unit test for crrev:2135046
* chore: update devtools-protocol revision
Co-authored-by: Changhao Han <changhaohan@chromium.org>
Now the async hooks helper is gone api.ts was only used by the coverage
tools and by doclint.
DocLint is nearing the end of its lifespan with the TSDoc work, so I
focused on how best to define a list of modules for the coverage
tooling. They define an object of classes, and the path to that module.
They need the full path because we also check if the module exports any
events that need to be emitted - the coverage tool asserts that the
emitting of those events is also tested.
It's not _great_ that DocLint relies on a constant defined in the
coverage utils, but it should only be this way for a short period of
time and no one is actively working on DocLint (bar the effort to remove
it) so I don't think this is worth worrying about.
This change also broke the DocLint tests; based on the fact that DocLint is on its way out it doesn't feel worth fixing the tests, so this commit also removes them.
* chore: remove `installAsyncStackHooks` helper
This code was written when browsers/Node didn't support errors in async
functions very well. They now do a much better job of this, so we can
lose the additonal complexity from our codebase and leave it to the host
environment :)
* lazy launcher is private
* remove async stack test
This pulls in the types (based on the DefinitelyTyped repo) for
`page.$eval` (and the `$eval` method on other classes). The `$eval`
method is quite hard to type due to the way we wrap and unwrap
ElementHandles that are passed to / returned from the `pageFunction`
that users provide.
Longer term we can improve the types by providing type overloads as
DefinitelyTyped does but I've deferred that for now (see the `TODO` in
the code for more details).
This change started as a small change to pull types from DefinitelyTyped over to
Puppeteer for the `evaluateHandle` function but instead ended up also fixing
what looks to be a long standing issue with our existing documentation.
`evaluateHandle` can in fact return an `ElementHandle` rather than a `JSHandle`.
Note that `ElementHandle` extends `JSHandle` so whilst the docs are technically
correct (all ElementHandles are JSHandles) it's confusing because JSHandles
don't have methods like `click` on them, but ElementHandles do.
if you return something that is an HTML element:
```
const button = page.evaluateHandle(() => document.querySelector('button'));
// this is an ElementHandle, not a JSHandle
```
Therefore I've updated the original docs and added a large explanation to the
TSDoc for `page.evaluateHandle`.
In TypeScript land we'll assume the function will return a `JSHandle` but you
can tell TS otherwise via the generic argument, which can only be `JSHandle`
(the default) or `ElementHandle`:
```
const button = page.evaluateHandle<ElementHandle>(() => document.querySelector('button'));
```
The headful one I'm permanently skipping as I don't know what the issue is and I can't debug without getting my hands on a Windows machine. If anyone has one or is able to help, that'd be great!
The other I'm deferring another month and will ping the FF folks :)
This CL migrates all the tests to TypeScript. The main benefits of this is that we start consuming our TypeScript definitions and therefore find errors in them. The act of migrating found some bugs in our definitions and now we can be sure to avoid them going forwards.
You'll notice the addition of some `TODO`s in the code; I didn't want this CL to get any bigger than it already is but I intend to follow those up once this lands. It's mostly figuring out how to extend the `expect` types with our `toBeGolden` helpers and some other slight confusions with types that the tests exposed.
Co-authored-by: Mathias Bynens <mathias@qiwi.be>
As far as I can tell these became irrelevant as of v1.15 which added
`puppeteer.errors` and `puppeteer.devices [1]. This is a breaking change
but one that's easily mitigated. We've said that we don't consider
changes to our folder/file structure a breaking change, but we can't
really do that if we have these two top level files that we've
documented.
[1]: e3abb0aa32 (diff-522b24108d7446af4c59873472a90444)
These files will be used by both the web and node versions of Puppeteer.
Another name for this might be "core" but I don't want to cause
confusion with the puppeteer-core package that we publish at the moment.
Fix child process killing when the parent process SIGINTs.
If you `ctrl + c` the Puppeteer parent process, we would sometimes not properly handle killing of the child processes. This would then leave child processes behind, with running Chromium instances. This in turn could block Puppeteer from launching again and results in
cryptic errors.
Instead of using the generic `process.kill` with the process id (which for some reason is negative the pid, which I don't get), we can kill the child process directly by calling `proc.kill`.
Fixes#5729.
Fixes#4796.
Fixes#4963.
Fixes#4333.
Fixes#1825.
* chore: remove "Extracting..." log message
Fixes#5741.
* test: support extra Launcher options and skips
The extra Launcher options and skipping conditions enable
unit tests to be run more easily by third-parties, e.g.
browser vendors that are interested in Puppeteer support.
Extra Launcher options were previously removed as part of
switching away from the custom test harness.
* test: enable more tests for Firefox
We deferred this initially because our Windows CI built wasn't stable
and so debugging this was hard. It's now much more stable so let's push
this back a month but at the same time I'll reach out to the Moz folks
as it should be easier to debug reliably now CI is stable on Windows.
* Don't use expect within Promises (#5466)
If a call to expect fails within a Promise it will not
be resolved, and causing the test to crash.
The patch aligns the code similar to what is used by all
the other tests.
* chore: fix invalid SSL assertion on Catalina
The error Chrome gives with an invalid cert changes between older Mac
versions and Catalina as detailed here:
https://support.google.com/chrome/thread/18125056?hl=en.
This PR changes Travis to run Catalina (and we think most devs run up to
date OS versions) so this fix ensures the test behaviour is consistent
locally and on Travis.
For those on older Mac versions I've left a comment by the tests to
hopefully save them debugging!
Co-authored-by: Mathias Bynens <mathias@qiwi.be>
The coverage utils depend on `src/api.ts` being up to date and pointing to the right modules. If they aren't, you would get a cryptic error on CI:
```
1) "before all" hook in "{root}":
TypeError: Cannot read property 'prototype' of undefined
at traceAPICoverage (test/coverage-utils.js:40:54)
at Context.before (test/coverage-utils.js:103:7)
2) "after all" hook in "{root}":
TypeError: Cannot read property 'stop' of undefined
at Context.after (test/mocha-utils.js:168:22)
```
This change logs a clearer error that highlights the missing class and exits, so it's much easier to realise what's gone wrong.
Ideally the coverage wouldn't need a hardcoded list of sources, but until then this will help spot this error in the future.
This corresponds to Chromium 83.0.4103.0.
This roll includes:
- Enable SameSiteByDefaultCookies and CookiesWithoutSameSiteMustBeSecure https://crrev.com/c/2122809
When this test was failing, it would cause no future tests to run. This
was because the `expect` call within the `page.on` callback would throw
an error, and that would trigger a unhandled promise rejection that
caused the test framework to stop.
The fundamental issue here is making `expect` calls within callbacks.
They are brittle due to the fact that they throw, and the test framework
won't catch it, but also because you have no guarantee that they will
run. If the callback is never executed you dont' know about it.
Although it's slightly more code, using a stub is the way to do this.
Not only can we assert that the stub was called, we can make synchronous
`expect` calls that Mocha will pick up properly if they fail.
Before this change, running the tests (and making it fail on purpose)
would cause all test execution to stop:
```
> puppeteer@3.0.4-post unit /Users/jacktfranklin/src/puppeteer
> mocha --config mocha-config/puppeteer-unit-tests.js
.(node:69580) UnhandledPromiseRejectionWarning: Error: expect(received).toBe(expected) // Object.is equality
Expected: "yes."
Received: ""
at Page.<anonymous> (/Users/jacktfranklin/src/puppeteer/test/dialog.spec.js:42:37)
[snip]
(node:69580) UnhandledPromiseRejectionWarning: Unhandled promise rejection ... [snip]
```
But with this change, the rest of the tests run:
```
> puppeteer@3.0.4-post unit /Users/jacktfranklin/src/puppeteer
> mocha --config mocha-config/puppeteer-unit-tests.js
Page.Events.Dialog
✓ should fire
1) should allow accepting prompts
✓ should dismiss the prompt
2 passing (2s)
1 failing
1) Page.Events.Dialog
should allow accepting prompts:
Error: expect(received).toBe(expected) // Object.is equality
Expected: "yes."
Received: ""
at Context.<anonymous> (test/dialog.spec.js:53:35)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
```
This is much better because one failing test now doesn't stop the rest
of the test suite.
This probably isn't the only instance of this in the codebase so I
propose as we encounter them we fix them usng this commit as the
template.
* Warn when given unsupported product name.
Fixes#5844.
This change means when a user launches Puppeteer with a product name
that is not supported (which at the time of this commit means it's not
`firefox` or `chrome) we will warn them about it.
Decided on just a warning vs an error because the current behaviour is
that we fallback to launching Chrome and I don't think this warrants a
breaking change.
* chore: update how we track coverage during unit tests
The old method of tracking coverage was causing issues. If a test failed
on CI, that test's failure would be lost because the test failing would
in turn cause the coverage to fail, but the `process.exit(1)` in the
coverage code caused Mocha to not output anything useful.
Instead the coverage checker now:
* tracks the coverage in memory in a Map (this hasn't changed)
* after all tests, writes that to disk in test/coverage.json (which is
gitignored)
* we then run a single Mocha test that asserts every method was called.
This means if the test run fails, the build will fail and give the error
about that test run, and that output won't be lost when the coverage
then fails too.
Co-authored-by: Mathias Bynens <mathias@qiwi.be>
The codebase was incredibly inconsistent with the use of spacing around
curly braces, e.g.:
```
// this?
const a = {b: 1}
// or?
const a = { b: 1 }
```
This extended into import statements also. Google's styleguide is no
spacing, so we're going with that.
* chore: Add Windows to Travis
This commit runs the unit tests on Windows.
There are two tests failing on Windows that we skip.
I spoke to Mathias B and we agreed to
defer debugging this for now in favour of getting tests running on
Windows. But we didn't want to ignore it forever, hence giving the test
a date at which it will start to fail.
This commit updates all the non-Puppeteer unit tests to run using Mocha and then deletes the custom test runner framework from this repository. The documentation has also been updated.
Rather than maintain our own test runner we should instead lean on the community and use Mocha which is very popular and also our test runner of choice in DevTools too.
Note that this commit doesn't remove the TestRunner source as it's still used for other unit tests, but they will be updated in a future PR and then we can remove the TestRunner.
The main bulk of this PR is updating the tests as the old TestRunner passed in contextual data via the `it` function callback whereas Mocha does not, so we introduce some helpers for the tests to make it easier.
See the large code comment in the diff for a full explanation but we can't rely on the functions being referentially equivalent so instead we test the behaviour in duplicate tests across the deprecated method and the new method.
They fail because cookies in Firefox return a `sameSite` key which the tests don't expect.
This is a solution that at least gets the Travis Firefox build (hopefully!) green again. Longer term it'd be great to allow the assertion to change based on the browser, rather than skip these tests entirely.
Rather than use our own custom expect library, we can use expect from npm [1], which has an API almost identical to the one Puppeteer has, but with more options, better diffing, and is used by many in the community as it's the default assertions library that comes with Jest.
It's also thoroughly documented [2].
[1]: https://www.npmjs.com/package/expect
[2]: https://jestjs.io/docs/en/expect
* (feat) Add option to fetch Firefox Nightly
Add Firefox support to BrowserFetcher and the install script.
By default, the latest Firefox Nightly is downloaded
directly from archive.mozilla.org (dmg, tar.bz2 and zip)
This also required changes that impact `puppeteer.launch()`
and `puppeteer.executablePath()`
Fixes#5151
* Update docs/api.md
Co-Authored-By: Mathias Bynens <mathias@qiwi.be>
* Clean up revision promise
* Improve error handling in revision check
* Remove matchAll
* Use explicit octal mode
* Update .gitignore
Co-authored-by: Mathias Bynens <mathias@qiwi.be>