fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

243
node_modules/expect-puppeteer/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,243 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [4.4.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v4.3.0...v4.4.0) (2019-12-18)
### Bug Fixes
* fix toDisplayDialog ([ce9df04](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/ce9df04642720a6af23e9b25f1b341bc82eca564))
### Features
* increase peerDependencies to allow Puppeteer v2 ([#289](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/289)) ([62a9b81](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/62a9b819cebf67d7e7b36453b79fba06390585ca))
* **expect-puppeteer:** support frames ([#275](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/275)) ([09703ea](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/09703eaeeeab553e13142153b55030db05611f7c))
# [4.3.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v4.2.0...v4.3.0) (2019-07-14)
**Note:** Version bump only for package expect-puppeteer
## [4.1.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v4.1.0...v4.1.1) (2019-04-11)
**Note:** Version bump only for package expect-puppeteer
# [4.1.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v4.0.0...v4.1.0) (2019-03-14)
### Features
* **expect-puppeteer:** add visibility option to toMatchElement ([#208](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/208)) ([46d8ec1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/46d8ec1))
# [4.0.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.9.0...v4.0.0) (2019-02-13)
**Note:** Version bump only for package expect-puppeteer
## [3.5.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.5.0...v3.5.1) (2018-11-11)
**Note:** Version bump only for package expect-puppeteer
<a name="3.4.0"></a>
# [3.4.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.3.1...v3.4.0) (2018-09-24)
### Bug Fixes
* support several instances of Jest in parallel ([#138](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/138)) ([275bc71](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/275bc71))
### Features
* **expect-puppeteer:** Update default options to look at connect object ([1f33ea0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/1f33ea0))
* connect to an already existing instance of Chrome ([#100](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/100)) ([3fcbaf8](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/3fcbaf8))
<a name="3.3.0"></a>
# [3.3.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.2.1...v3.3.0) (2018-08-15)
**Note:** Version bump only for package expect-puppeteer
<a name="3.2.0"></a>
# [3.2.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.1.0...v3.2.0) (2018-06-17)
**Note:** Version bump only for package expect-puppeteer
<a name="3.1.0"></a>
# [3.1.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.0.1...v3.1.0) (2018-06-16)
**Note:** Version bump only for package expect-puppeteer
<a name="3.0.1"></a>
## [3.0.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v3.0.0...v3.0.1) (2018-05-03)
### Bug Fixes
* **expect-puppeteer:** use the same behaviour on toMatch and toMatchElement ([784bde8](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/784bde8))
<a name="3.0.0"></a>
# [3.0.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.4.0...v3.0.0) (2018-05-03)
### Features
* **expect-puppeteer:** added delay option to element.type for toFill matcher ([#52](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/52)) ([ee39ba9](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/ee39ba9))
* **expect-puppeteer:** enhance toMatchElement / toClick text option ([cee8f46](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/cee8f46)), closes [#51](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/51) [#50](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/50)
### BREAKING CHANGES
* **expect-puppeteer:** Text is now trimmed and no longer evaluated as a RegExp. If you want this behaviour, use a true RegExp.
<a name="2.4.0"></a>
# [2.4.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.3.0...v2.4.0) (2018-04-24)
### Features
* **expect-puppeteer:** keep original error message ([#45](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/45)) ([72b60a9](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/72b60a9)), closes [#33](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/33)
* **expect-puppeteer:** make default options configurable ([#46](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/46)) ([0d493c4](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/0d493c4))
* adjust default timeout with slowMo ([6871ec8](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/6871ec8)), closes [#36](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/36)
<a name="2.3.0"></a>
# [2.3.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.2.3...v2.3.0) (2018-04-06)
**Note:** Version bump only for package expect-puppeteer
<a name="2.2.2"></a>
## [2.2.2](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.2.1...v2.2.2) (2018-04-01)
### Bug Fixes
* **expect-puppeteer:** reduce chance of collision ([83ade43](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/83ade43)), closes [#issuecomment-377698539](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/issuecomment-377698539)
<a name="2.2.1"></a>
## [2.2.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.2.0...v2.2.1) (2018-03-25)
### Bug Fixes
* support original Jest matchers ([99d542e](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/commit/99d542e)), closes [#17](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/issues/17)
<a name="2.2.0"></a>
# [2.2.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer/compare/v2.1.0...v2.2.0) (2018-03-17)
**Note:** Version bump only for package expect-puppeteer
<a name="2.1.0"></a>
# [2.1.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/compare/v2.0.1...v2.1.0) (2018-03-16)
### Features
* add element handle support ([4d37d5b](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/commit/4d37d5b))
<a name="2.0.1"></a>
## [2.0.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/compare/v2.0.0...v2.0.1) (2018-03-08)
### Bug Fixes
* **expect-puppeteer:** fix expectMatch when body is undefined ([#9](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/issues/9)) ([0c60970](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/commit/0c60970))
<a name="2.0.0"></a>
# [2.0.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/compare/v1.1.1...v2.0.0) (2018-03-05)
### Features
* simplify expect usage ([e0fc3d1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/commit/e0fc3d1))
### BREAKING CHANGES
* `expectPage()` is replaced by `expect(page)`
<a name="1.1.1"></a>
## [1.1.1](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/compare/v1.1.0...v1.1.1) (2018-03-04)
### Bug Fixes
* **expect-puppeteer:** add all sources in pkg ([bb51870](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/commit/bb51870))
<a name="1.1.0"></a>
# [1.1.0](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/compare/v1.0.1...v1.1.0) (2018-03-04)
### Features
* add spawnd & expect-puppeteer ([6b7f5a4](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/puppeteer-expect/commit/6b7f5a4))

7
node_modules/expect-puppeteer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2018 Smooth Code
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

240
node_modules/expect-puppeteer/README.md generated vendored Normal file
View File

@@ -0,0 +1,240 @@
# expect-puppeteer
[![Build Status][build-badge]][build]
[![version][version-badge]][package]
[![MIT License][license-badge]][license]
Assertion library for Puppeteer.
```
npm install expect-puppeteer
```
## Usage
Without Jest:
```js
import expect from 'expect-puppeteer'
;(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://google.com')
await expect(page).toMatch('google')
await browser.close()
})()
```
## Use with Jest
To use with Jest, just modify your configuration:
```json
{
"setupFilesAfterEnv": ["expect-puppeteer"]
}
```
## Why do I need it
Writing integration test is very hard, especially when you are testing a Single Page Applications. Data are loaded asynchronously and it is difficult to know exactly when an element will be displayed in the page.
[Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md) is great, but it is low level and not designed for integration testing.
This API is designed for integration testing:
- It will wait for element before running an action
- It adds additional feature like matching an element using text
**Example**
```js
// Does not work if button is not in page
await page.click('button')
// Will try while 500ms to click on "button"
await page.toClick('button')
// Will match a button with a "My button" text inside
await page.toClick('button', { text: 'My button' })
```
## API
##### Table of Contents
<!-- toc -->
- [toClick](#toClick)
- [toDisplayDialog](#toDisplayDialog)
- [toFill](#toFill)
- [toFillForm](#toFillForm)
- [toMatch](#toMatch)
- [toMatchElement](#toMatchElement)
- [toSelect](#toSelect)
- [toUploadFile](#toUploadFile)
### <a name="toClick"></a>expect(instance).toClick(selector[, options])
Expect an element to be in the page or element, then click on it.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to click on
- `options` <[Object]> Optional parameters
- `button` <"left"|"right"|"middle"> Defaults to `left`.
- `clickCount` <[number]> defaults to 1. See [UIEvent.detail].
- `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0.
- `text` <[string]|[RegExp]> A text or a RegExp to match in element `textContent`.
```js
await expect(page).toClick('button', { text: 'Home' })
```
### <a name="toDisplayDialog"></a>expect(page).toDisplayDialog(block)
Expect block function to trigger a dialog and returns it.
- `page` <[Page]> Context
- `block` <[function]> A [function] that should trigger a dialog
```js
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick('button', { text: 'Show dialog' })
})
```
### <a name="toFill"></a>expect(instance).toFill(selector, value[, options])
Expect a control to be in the page or element, then fill it with text.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to match field
- `value` <[string]> Value to fill
- `options` <[Object]> Optional parameters
- `delay` <[number]> delay to pass to [the puppeteer `element.type` API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#elementhandletypetext-options)
```js
await expect(page).toFill('input[name="firstName"]', 'James')
```
### <a name="toFillForm"></a>expect(instance).toFillForm(selector, values[, options])
Expect a form to be in the page or element, then fill its controls.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to match form
- `values` <[Object]> Values to fill
- `options` <[Object]> Optional parameters
- `delay` <[number]> delay to pass to [the puppeteer `element.type` API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#elementhandletypetext-options)
```js
await expect(page).toFillForm('form[name="myForm"]', {
firstName: 'James',
lastName: 'Bond',
})
```
### <a name="toMatch"></a>expect(instance).toMatch(matcher[, options])
Expect a text or a string RegExp to be present in the page or element.
- `instance` <[Page]|[ElementHandle]> Context
- `matcher` <[string]|[RegExp]> A text or a RegExp to match in page
- `options` <[Object]> Optional parameters
- `polling` <[string]|[number]> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it can be one of the following values:
- `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` callback. This is the tightest polling mode which is suitable to observe styling changes.
- `mutation` - to execute `pageFunction` on every DOM mutation.
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
```js
// Matching using text
await expect(page).toMatch('Lorem ipsum')
// Matching using RegExp
await expect(page).toMatch(/lo.*/)
```
### <a name="toMatchElement"></a>expect(instance).toMatchElement(selector[, options])
Expect an element be present in the page or element.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to match element
- `options` <[Object]> Optional parameters
- `polling` <[string]|[number]> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it can be one of the following values:
- `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` callback. This is the tightest polling mode which is suitable to observe styling changes.
- `mutation` - to execute `pageFunction` on every DOM mutation.
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
- `text` <[string]|[RegExp]> A text or a RegExp to match in element `textContent`.
- `visible` <[boolean]> wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
```js
// Select a row containing a text
const row = await expect(page).toMatchElement('tr', { text: 'My row' })
// Click on the third column link
await expect(row).toClick('td:nth-child(2) a')
```
### <a name="toSelect"></a>expect(instance).toSelect(selector, valueOrText)
Expect a select control to be present in the page or element, then select the specified option.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to match select [element]
- `valueOrText` <[string]> Value or text matching option
```js
await expect(page).toSelect('select[name="choices"]', 'Choice 1')
```
### <a name="toUploadFile"></a>expect(instance).toUploadFile(selector, filePath)
Expect a input file control to be present in the page or element, then fill it with a local file.
- `instance` <[Page]|[ElementHandle]> Context
- `selector` <[string]> A [selector] to match input [element]
- `filePath` <[string]> A file path
```js
import path from 'path'
await expect(page).toUploadFile(
'input[type="file"]',
path.join(__dirname, 'file.txt'),
)
```
## Configure default options
To configure default options like `timeout`, `expect-puppeteer` exposes two methods: `getDefaultOptions` and `setDefaultOptions`. You can find available options in [Puppeteer `page.waitForFunction` documentation](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforfunctionpagefunction-options-args). Default options are set to: `{ timeout: 500 }`.
```js
import { setDefaultOptions } from 'expect-puppeteer'
setDefaultOptions({ timeout: 1000 })
```
## License
MIT
[build-badge]: https://img.shields.io/travis/smooth-code/jest-puppeteer.svg?style=flat-square
[build]: https://travis-ci.org/smooth-code/jest-puppeteer
[version-badge]: https://img.shields.io/npm/v/expect-puppeteer.svg?style=flat-square
[package]: https://www.npmjs.com/package/expect-puppeteer
[license-badge]: https://img.shields.io/npm/l/expect-puppeteer.svg?style=flat-square
[license]: https://github.com/smooth-code/jest-puppeteer/blob/master/LICENSE
[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 'Array'
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type 'Boolean'
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function 'Function'
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type 'Number'
[object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object 'Object'
[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise 'Promise'
[regexp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp 'RegExp'
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type 'String'
[error]: https://nodejs.org/api/errors.html#errors_class_error 'Error'
[element]: https://developer.mozilla.org/en-US/docs/Web/API/element 'Element'
[map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map 'Map'
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors 'selector'
[page]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page 'Page'
[elementhandle]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-elementhandle 'ElementHandle'
[uievent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

128
node_modules/expect-puppeteer/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,128 @@
"use strict";
var _utils = require("./utils");
var _notToMatch = _interopRequireDefault(require("./matchers/notToMatch"));
var _notToMatchElement = _interopRequireDefault(require("./matchers/notToMatchElement"));
var _toClick = _interopRequireDefault(require("./matchers/toClick"));
var _toDisplayDialog = _interopRequireDefault(require("./matchers/toDisplayDialog"));
var _toFill = _interopRequireDefault(require("./matchers/toFill"));
var _toFillForm = _interopRequireDefault(require("./matchers/toFillForm"));
var _toMatch = _interopRequireDefault(require("./matchers/toMatch"));
var _toMatchElement = _interopRequireDefault(require("./matchers/toMatchElement"));
var _toSelect = _interopRequireDefault(require("./matchers/toSelect"));
var _toUploadFile = _interopRequireDefault(require("./matchers/toUploadFile"));
var _options = require("./options");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const pageMatchers = {
toClick: _toClick.default,
toDisplayDialog: _toDisplayDialog.default,
toFill: _toFill.default,
toFillForm: _toFillForm.default,
toMatch: _toMatch.default,
toMatchElement: _toMatchElement.default,
toSelect: _toSelect.default,
toUploadFile: _toUploadFile.default,
not: {
toMatch: _notToMatch.default,
toMatchElement: _notToMatchElement.default
}
};
const elementHandleMatchers = {
toClick: _toClick.default,
toFill: _toFill.default,
toFillForm: _toFillForm.default,
toMatch: _toMatch.default,
toMatchElement: _toMatchElement.default,
toSelect: _toSelect.default,
toUploadFile: _toUploadFile.default,
not: {
toMatch: _notToMatch.default,
toMatchElement: _notToMatchElement.default
}
};
function createMatcher(matcher, page) {
return async function throwingMatcher(...args) {
if (typeof global.expect !== 'undefined') {
global.expect.getState().assertionCalls += 1;
}
try {
return await matcher(page, ...args);
} catch (error) {
Error.captureStackTrace(error, createMatcher);
throw error;
}
};
}
function internalExpect(type, matchers) {
const expectation = {
not: {}
};
Object.keys(matchers).forEach(key => {
if (key === 'not') return;
expectation[key] = createMatcher(matchers[key], type);
});
Object.keys(matchers.not).forEach(key => {
expectation.not[key] = createMatcher(matchers.not[key], type);
});
return expectation;
}
function expectPuppeteer(actual) {
const type = (0, _utils.getPuppeteerType)(actual);
switch (type) {
case 'Page':
case 'Frame':
return internalExpect(actual, pageMatchers);
case 'ElementHandle':
return internalExpect(actual, elementHandleMatchers);
default:
throw new Error(`${actual} is not supported`);
}
}
if (typeof global.expect !== 'undefined') {
const originalExpect = global.expect;
global.expect = (actual, ...args) => {
const type = (0, _utils.getPuppeteerType)(actual);
if (type) {
const matchers = expectPuppeteer(actual);
const jestMatchers = originalExpect(actual, ...args);
return _extends({}, jestMatchers, {}, matchers, {
not: _extends({}, jestMatchers.not, {}, matchers.not)
});
}
return originalExpect(actual, ...args);
};
Object.keys(originalExpect).forEach(prop => {
global.expect[prop] = originalExpect[prop];
});
}
module.exports = expectPuppeteer;
module.exports.setDefaultOptions = _options.setDefaultOptions;
module.exports.getDefaultOptions = _options.getDefaultOptions;

View File

@@ -0,0 +1,28 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _options = require("../options");
async function notToMatch(instance, matcher, options) {
options = (0, _options.defaultOptions)(options);
const {
page,
handle
} = await (0, _utils.getContext)(instance, () => document.body);
try {
await page.waitForFunction((handle, matcher) => {
if (!handle) return false;
return handle.textContent.match(new RegExp(matcher)) === null;
}, options, handle, matcher);
} catch (error) {
throw (0, _utils.enhanceError)(error, `Text found "${matcher}"`);
}
}
var _default = notToMatch;
exports.default = _default;

View File

@@ -0,0 +1,42 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _options = require("../options");
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
async function notToMatchElement(instance, selector, _ref = {}) {
let {
text
} = _ref,
options = _objectWithoutPropertiesLoose(_ref, ["text"]);
options = (0, _options.defaultOptions)(options);
const {
page,
handle
} = await (0, _utils.getContext)(instance, () => document);
try {
await page.waitForFunction((handle, selector, text) => {
const elements = handle.querySelectorAll(selector);
if (text !== undefined) {
return [...elements].every(({
textContent
}) => !textContent.match(text));
}
return elements.length === 0;
}, options, handle, selector, text);
} catch (error) {
throw (0, _utils.enhanceError)(error, `Element ${selector}${text !== undefined ? ` (text: "${text}") ` : ' '}found`);
}
}
var _default = notToMatchElement;
exports.default = _default;

View File

@@ -0,0 +1,39 @@
"use strict";
exports.__esModule = true;
exports.setupPage = void 0;
function waitForFrame(page) {
let fulfill;
const promise = new Promise(resolve => {
fulfill = resolve;
});
function checkFrame() {
const frame = page.frames().find(f => f.parentFrame() !== null);
if (frame) fulfill(frame);else page.once(`frameattached`, checkFrame);
}
checkFrame();
return promise;
}
const setupPage = (pageType, cb) => {
let currentPage = page;
beforeEach(async () => {
if (pageType === `Page`) {
cb({
currentPage
});
return;
}
await page.goto(`http://localhost:${process.env.TEST_SERVER_PORT}/frame.html`);
currentPage = await waitForFrame(page);
cb({
currentPage
});
});
};
exports.setupPage = setupPage;

16
node_modules/expect-puppeteer/lib/matchers/toClick.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _toMatchElement = _interopRequireDefault(require("./toMatchElement"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
async function toClick(instance, selector, options) {
const element = await (0, _toMatchElement.default)(instance, selector, options);
await element.click(options);
}
var _default = toClick;
exports.default = _default;

View File

@@ -0,0 +1,19 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
async function toDisplayDialog(page, block) {
return new Promise((resolve, reject) => {
const handleDialog = dialog => {
page.removeListener('dialog', handleDialog);
resolve(dialog);
};
page.on('dialog', handleDialog);
block().catch(reject);
});
}
var _default = toDisplayDialog;
exports.default = _default;

29
node_modules/expect-puppeteer/lib/matchers/toFill.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _toMatchElement = _interopRequireDefault(require("./toMatchElement"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
async function toFill(instance, selector, value, options) {
const _ref = options || {},
{
delay
} = _ref,
toMatchElementOptions = _objectWithoutPropertiesLoose(_ref, ["delay"]);
const element = await (0, _toMatchElement.default)(instance, selector, toMatchElementOptions);
await element.click({
clickCount: 3
});
await element.type(value, {
delay
});
}
var _default = toFill;
exports.default = _default;

View File

@@ -0,0 +1,25 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _options = require("../options");
var _toFill = _interopRequireDefault(require("./toFill"));
var _toMatchElement = _interopRequireDefault(require("./toMatchElement"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-restricted-syntax, no-await-in-loop */
async function toFillForm(instance, selector, values, options) {
options = (0, _options.defaultOptions)(options);
const form = await (0, _toMatchElement.default)(instance, selector, options);
for (const name of Object.keys(values)) {
await (0, _toFill.default)(form, `[name="${name}"]`, values[name], options);
}
}
var _default = toFillForm;
exports.default = _default;

42
node_modules/expect-puppeteer/lib/matchers/toMatch.js generated vendored Normal file
View File

@@ -0,0 +1,42 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _options = require("../options");
async function toMatch(instance, matcher, options) {
options = (0, _options.defaultOptions)(options);
const {
page,
handle
} = await (0, _utils.getContext)(instance, () => document.body);
const {
text,
regexp
} = (0, _utils.expandSearchExpr)(matcher);
try {
await page.waitForFunction((handle, text, regexp) => {
if (!handle) return false;
if (regexp !== null) {
const [, pattern, flags] = regexp.match(/\/(.*)\/(.*)?/);
return handle.textContent.replace(/\s+/g, ' ').trim().match(new RegExp(pattern, flags)) !== null;
}
if (text !== null) {
return handle.textContent.replace(/\s+/g, ' ').trim().includes(text);
}
return false;
}, options, handle, text, regexp);
} catch (error) {
throw (0, _utils.enhanceError)(error, `Text not found "${matcher}"`);
}
}
var _default = toMatch;
exports.default = _default;

View File

@@ -0,0 +1,73 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _options = require("../options");
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
async function toMatchElement(instance, selector, _ref = {}) {
let {
text: searchExpr,
visible = false
} = _ref,
options = _objectWithoutPropertiesLoose(_ref, ["text", "visible"]);
options = (0, _options.defaultOptions)(options);
const {
page,
handle
} = await (0, _utils.getContext)(instance, () => document);
const {
text,
regexp
} = (0, _utils.expandSearchExpr)(searchExpr);
const getElement = (handle, selector, text, regexp, visible) => {
function hasVisibleBoundingBox(element) {
const rect = element.getBoundingClientRect();
return !!(rect.top || rect.bottom || rect.width || rect.height);
}
const isVisible = element => {
if (visible) {
const style = window.getComputedStyle(element);
return style && style.visibility !== 'hidden' && hasVisibleBoundingBox(element);
}
return true;
};
const elements = [...handle.querySelectorAll(selector)].filter(isVisible);
if (regexp !== null) {
const [, pattern, flags] = regexp.match(/\/(.*)\/(.*)?/);
return elements.find(({
textContent
}) => textContent.replace(/\s+/g, ' ').trim().match(new RegExp(pattern, flags)));
}
if (text !== null) {
return elements.find(({
textContent
}) => textContent.replace(/\s+/g, ' ').trim().includes(text));
}
return elements[0];
};
try {
await page.waitForFunction(getElement, options, handle, selector, text, regexp, visible);
} catch (error) {
throw (0, _utils.enhanceError)(error, `Element ${selector}${text !== null || regexp !== null ? ` (text: "${text || regexp}") ` : ' '}not found`);
}
const jsHandle = await page.evaluateHandle(getElement, handle, selector, text, regexp, visible);
return jsHandle.asElement();
}
var _default = toMatchElement;
exports.default = _default;

80
node_modules/expect-puppeteer/lib/matchers/toSelect.js generated vendored Normal file
View File

@@ -0,0 +1,80 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _toMatchElement = _interopRequireDefault(require("./toMatchElement"));
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-restricted-syntax */
function select(page, element, value) {
return page.evaluate((element, value) => {
if (element.nodeName.toLowerCase() !== 'select') throw new Error('Element is not a <select> element.');
const options = Array.from(element.options);
element.value = undefined;
for (const option of options) {
option.selected = value === option.value;
if (option.selected && !element.multiple) break;
}
element.dispatchEvent(new Event('input', {
bubbles: true
}));
element.dispatchEvent(new Event('change', {
bubbles: true
}));
return options.filter(option => option.selected).map(option => option.value);
}, element, value);
}
async function toSelect(instance, selector, valueOrText, options) {
const element = await (0, _toMatchElement.default)(instance, selector, options);
const optionElements = await element.$$('option');
const optionsAttributes = await Promise.all(optionElements.map(async option => {
const textContentProperty = await option.getProperty('textContent');
const valueProperty = await option.getProperty('value');
return {
value: await valueProperty.jsonValue(),
textContent: await textContentProperty.jsonValue()
};
}));
const option = optionsAttributes.find(({
value,
textContent
}) => value === valueOrText || textContent === valueOrText);
if (!option) {
throw new Error(`Option not found "${selector}" ("${valueOrText}")`);
}
const {
page
} = await (0, _utils.getContext)(instance, () => document);
await select(page, element, option.value); // await page.select(selector, foundValue)
// console.log(select.select)
// select.select()
// const foundValue = await select.$$eval(
// `${selector} option`,
// (options, valueOrText, selector) => {
// const option = options.find(
// option =>
// option.value === valueOrText || option.textContent === valueOrText,
// )
// if (!option) {
// throw new Error(`Option not found "${selector}" ("${valueOrText}")`)
// }
// return option.value
// },
// valueOrText,
// selector,
// )
//
// await page.select(selector, foundValue)
}
var _default = toSelect;
exports.default = _default;

View File

@@ -0,0 +1,17 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _toMatchElement = _interopRequireDefault(require("./toMatchElement"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
async function toUploadFile(instance, selector, file, options) {
const input = await (0, _toMatchElement.default)(instance, selector, options);
const files = Array.isArray(file) ? file : [file];
await input.uploadFile(...files);
}
var _default = toUploadFile;
exports.default = _default;

35
node_modules/expect-puppeteer/lib/options.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
exports.__esModule = true;
exports.defaultOptions = exports.getDefaultOptions = exports.setDefaultOptions = void 0;
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
let defaultOptionsValue = {
timeout: 500
};
const setDefaultOptions = options => {
defaultOptionsValue = options;
};
exports.setDefaultOptions = setDefaultOptions;
const getDefaultOptions = () => {
if (global.puppeteerConfig && (global.puppeteerConfig.launch && global.puppeteerConfig.launch.slowMo || global.puppeteerConfig.connect && global.puppeteerConfig.connect.slowMo) && defaultOptionsValue && defaultOptionsValue.timeout) {
return _extends({}, defaultOptionsValue, {
// Multiplying slowMo by 10 is just arbitrary
// slowMo is applied on all Puppeteer internal methods, so it is just a "slow" indicator
// we can't use it as a real value
timeout: defaultOptionsValue.timeout + global.puppeteerConfig.launch.slowMo * 10
});
}
return defaultOptionsValue;
};
exports.getDefaultOptions = getDefaultOptions;
const defaultOptions = options => _extends({}, getDefaultOptions(), {}, options);
exports.defaultOptions = defaultOptions;

67
node_modules/expect-puppeteer/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
"use strict";
exports.__esModule = true;
exports.expandSearchExpr = exports.enhanceError = exports.getContext = exports.getPuppeteerType = void 0;
const getPuppeteerType = instance => {
if (instance && instance.constructor && instance.constructor.name && ['Page', 'Frame', 'ElementHandle'].includes(instance.constructor.name) && instance.$) {
return instance.constructor.name;
}
return null;
};
exports.getPuppeteerType = getPuppeteerType;
const getContext = async (instance, pageFunction) => {
const type = getPuppeteerType(instance);
switch (type) {
case 'Page':
case 'Frame':
return {
page: instance,
handle: await instance.evaluateHandle(pageFunction)
};
case 'ElementHandle':
{
const executionContext = await instance.executionContext();
return {
page: await executionContext.frame(),
handle: instance
};
}
default:
throw new Error(`${type} is not implemented`);
}
};
exports.getContext = getContext;
const enhanceError = (error, message) => {
error.message = `${message}\n${error.message}`;
return error;
};
exports.enhanceError = enhanceError;
const isRegExp = input => Object.prototype.toString.call(input) === '[object RegExp]';
const expandSearchExpr = expr => {
if (isRegExp(expr)) return {
text: null,
regexp: expr.toString()
};
if (typeof expr === 'string') return {
text: expr,
regexp: null
};
return {
text: null,
regexp: null
};
};
exports.expandSearchExpr = expandSearchExpr;

27
node_modules/expect-puppeteer/package.json generated vendored Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "expect-puppeteer",
"description": "Assertion toolkit for Puppeteer.",
"version": "4.4.0",
"main": "lib/index.js",
"repository": "https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer",
"author": "Greg Bergé <berge.greg@gmail.com>",
"license": "MIT",
"keywords": [
"jest",
"puppeteer",
"jest-puppeteer",
"chromeless",
"chrome-headless",
"expect",
"assert",
"should",
"assertion"
],
"scripts": {
"prebuild": "rm -rf lib/",
"build": "babel --config-file ../../babel.config.js -d lib --ignore \"**/*.test.js\" src",
"dev": "yarn build --watch",
"prepublishOnly": "yarn build"
},
"gitHead": "c28ecb7729bef11cee25e91b16d75fb34f81f07a"
}