This commit is contained in:
Lukáš Kaňka
2023-08-15 18:35:50 +02:00
commit ea3e372146
10019 changed files with 2548539 additions and 0 deletions

25
CyLukTs/lukan/node_modules/cypress/README.md generated vendored Normal file
View File

@ -0,0 +1,25 @@
# Cypress
Fast, easy and reliable testing for anything that runs in a browser.
## What is this?
[Cypress](https://www.cypress.io/) comes packaged as an `npm` module, which is all you need to get started testing.
After installing you'll be able to:
- Open Cypress from the CLI
- Run Cypress from the CLI
- `require` Cypress as a module
## Install
Please check our [system requirements](https://on.cypress.io/installing-cypress).
```sh
npm install --save-dev cypress
```
## Documentation
Please [visit our documentation](https://on.cypress.io/cli) for a full list of commands and examples.

10
CyLukTs/lukan/node_modules/cypress/angular/README.md generated vendored Normal file
View File

@ -0,0 +1,10 @@
# @cypress/angular
Mount Angular components in the open source [Cypress.io](https://www.cypress.io/) test runner
> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Angular Component Testing Docs](https://docs.cypress.io/guides/component-testing/angular/overview) for mounting Angular components. Installing and importing `mount` from `@cypress/angular` should only be done for advanced use-cases.
## Development
Run `yarn build` to compile and sync packages to the `cypress` cli package.
## [Changelog](./CHANGELOG.md)

View File

@ -0,0 +1,128 @@
/// <reference types="cypress" />
import { Type } from '@angular/core';
import { TestModuleMetadata, ComponentFixture, TestComponentRenderer } from '@angular/core/testing';
/**
* Additional module configurations needed while mounting the component, like
* providers, declarations, imports and even component @Inputs()
*
*
* @interface MountConfig
* @see https://angular.io/api/core/testing/TestModuleMetadata
*/
interface MountConfig<T> extends TestModuleMetadata {
/**
* @memberof MountConfig
* @description flag to automatically create a cy.spy() for every component @Output() property
* @example
* export class ButtonComponent {
* @Output clicked = new EventEmitter()
* }
*
* cy.mount(ButtonComponent, { autoSpyOutputs: true })
* cy.get('@clickedSpy).should('have.been.called')
*/
autoSpyOutputs?: boolean;
/**
* @memberof MountConfig
* @description flag defaulted to true to automatically detect changes in your components
*/
autoDetectChanges?: boolean;
/**
* @memberof MountConfig
* @example
* import { ButtonComponent } from 'button/button.component'
* it('renders a button with Save text', () => {
* cy.mount(ButtonComponent, { componentProperties: { text: 'Save' }})
* cy.get('button').contains('Save')
* })
*
* it('renders a button with a cy.spy() replacing EventEmitter', () => {
* cy.mount(ButtonComponent, {
* componentProperties: {
* clicked: cy.spy().as('mySpy)
* }
* })
* cy.get('button').click()
* cy.get('@mySpy').should('have.been.called')
* })
*/
componentProperties?: Partial<{
[P in keyof T]: T[P];
}>;
}
/**
* Type that the `mount` function returns
* @type MountResponse<T>
*/
declare type MountResponse<T> = {
/**
* Fixture for debugging and testing a component.
*
* @memberof MountResponse
* @see https://angular.io/api/core/testing/ComponentFixture
*/
fixture: ComponentFixture<T>;
/**
* The instance of the root component class
*
* @memberof MountResponse
* @see https://angular.io/api/core/testing/ComponentFixture#componentInstance
*/
component: T;
};
declare class CypressTestComponentRenderer extends TestComponentRenderer {
insertRootElement(rootElId: string): void;
removeAllRootElements(): void;
}
/**
* Mounts an Angular component inside Cypress browser
*
* @param component Angular component being mounted or its template
* @param config configuration used to configure the TestBed
* @example
* import { mount } from '@cypress/angular'
* import { StepperComponent } from './stepper.component'
* import { MyService } from 'services/my.service'
* import { SharedModule } from 'shared/shared.module';
* it('mounts', () => {
* mount(StepperComponent, {
* providers: [MyService],
* imports: [SharedModule]
* })
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* })
*
* // or
*
* it('mounts with template', () => {
* mount('<app-stepper></app-stepper>', {
* declarations: [StepperComponent],
* })
* })
*
* @see {@link https://on.cypress.io/mounting-angular} for more details.
*
* @returns A component and component fixture
*/
declare function mount<T>(component: Type<T> | string, config?: MountConfig<T>): Cypress.Chainable<MountResponse<T>>;
/**
* Creates a new Event Emitter and then spies on it's `emit` method
*
* @param {string} alias name you want to use for your cy.spy() alias
* @returns EventEmitter<T>
* @example
* import { StepperComponent } from './stepper.component'
* import { mount, createOutputSpy } from '@cypress/angular'
*
* it('Has spy', () => {
* mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } })
* cy.get('[data-cy=increment]').click()
* cy.get('@changeSpy').should('have.been.called')
* })
*/
declare const createOutputSpy: <T>(alias: string) => any;
export { CypressTestComponentRenderer, MountConfig, MountResponse, createOutputSpy, mount };

View File

@ -0,0 +1,332 @@
/**
* @cypress/angular v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
import 'zone.js';
import 'zone.js/testing';
import { CommonModule } from '@angular/common';
import { Injectable, Component, EventEmitter, SimpleChange, ErrorHandler } from '@angular/core';
import { getTestBed, TestComponentRenderer, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
/**
* @hack fixes "Mocha has already been patched with Zone" error.
*/
// @ts-ignore
window.Mocha['__zone_patch__'] = false;
let activeFixture = null;
function cleanup() {
// Not public, we need to call this to remove the last component from the DOM
try {
getTestBed().tearDownTestingModule();
}
catch (e) {
const notSupportedError = new Error(`Failed to teardown component. The version of Angular you are using may not be officially supported.`);
notSupportedError.docsUrl = 'https://on.cypress.io/component-framework-configuration';
throw notSupportedError;
}
getTestBed().resetTestingModule();
activeFixture = null;
}
// 'zone.js/testing' is not properly aliasing `it.skip` but it does provide `xit`/`xspecify`
// Written up under https://github.com/angular/angular/issues/46297 but is not seeing movement
// so we'll patch here pending a fix in that library
globalThis.it.skip = globalThis.xit;
let CypressAngularErrorHandler = class CypressAngularErrorHandler {
handleError(error) {
throw error;
}
};
CypressAngularErrorHandler = __decorate([
Injectable()
], CypressAngularErrorHandler);
/**
* Bootstraps the TestModuleMetaData passed to the TestBed
*
* @param {Type<T>} component Angular component being mounted
* @param {MountConfig} config TestBed configuration passed into the mount function
* @returns {MountConfig} MountConfig
*/
function bootstrapModule(component, config) {
var _a;
const testModuleMetaData = __rest(config, ["componentProperties"]);
if (!testModuleMetaData.declarations) {
testModuleMetaData.declarations = [];
}
if (!testModuleMetaData.imports) {
testModuleMetaData.imports = [];
}
if (!testModuleMetaData.providers) {
testModuleMetaData.providers = [];
}
// Replace default error handler since it will swallow uncaught exceptions.
// We want these to be uncaught so Cypress catches it and fails the test
testModuleMetaData.providers.push({
provide: ErrorHandler,
useClass: CypressAngularErrorHandler,
});
// check if the component is a standalone component
if ((_a = component.ɵcmp) === null || _a === void 0 ? void 0 : _a.standalone) {
testModuleMetaData.imports.push(component);
}
else {
testModuleMetaData.declarations.push(component);
}
if (!testModuleMetaData.imports.includes(CommonModule)) {
testModuleMetaData.imports.push(CommonModule);
}
return testModuleMetaData;
}
let CypressTestComponentRenderer = class CypressTestComponentRenderer extends TestComponentRenderer {
insertRootElement(rootElId) {
this.removeAllRootElements();
const rootElement = getContainerEl();
rootElement.setAttribute('id', rootElId);
}
removeAllRootElements() {
getContainerEl().innerHTML = '';
}
};
CypressTestComponentRenderer = __decorate([
Injectable()
], CypressTestComponentRenderer);
/**
* Initializes the TestBed
*
* @param {Type<T> | string} component Angular component being mounted or its template
* @param {MountConfig} config TestBed configuration passed into the mount function
* @returns {Type<T>} componentFixture
*/
function initTestBed(component, config) {
const componentFixture = createComponentFixture(component);
getTestBed().configureTestingModule(Object.assign({}, bootstrapModule(componentFixture, config)));
getTestBed().overrideProvider(TestComponentRenderer, { useValue: new CypressTestComponentRenderer() });
return componentFixture;
}
let WrapperComponent = class WrapperComponent {
};
WrapperComponent = __decorate([
Component({ selector: 'cy-wrapper-component', template: '' })
], WrapperComponent);
/**
* Returns the Component if Type<T> or creates a WrapperComponent
*
* @param {Type<T> | string} component The component you want to create a fixture of
* @returns {Type<T> | WrapperComponent}
*/
function createComponentFixture(component) {
if (typeof component === 'string') {
// getTestBed().overrideTemplate is available in v14+
// The static TestBed.overrideTemplate is available across versions
TestBed.overrideTemplate(WrapperComponent, component);
return WrapperComponent;
}
return component;
}
/**
* Creates the ComponentFixture
*
* @param {Type<T>} component Angular component being mounted
* @param {MountConfig<T>} config MountConfig
* @returns {ComponentFixture<T>} ComponentFixture
*/
function setupFixture(component, config) {
const fixture = getTestBed().createComponent(component);
setupComponent(config, fixture);
fixture.whenStable().then(() => {
var _a;
fixture.autoDetectChanges((_a = config.autoDetectChanges) !== null && _a !== void 0 ? _a : true);
});
return fixture;
}
/**
* Gets the componentInstance and Object.assigns any componentProperties() passed in the MountConfig
*
* @param {MountConfig} config TestBed configuration passed into the mount function
* @param {ComponentFixture<T>} fixture Fixture for debugging and testing a component.
* @returns {T} Component being mounted
*/
function setupComponent(config, fixture) {
let component = fixture.componentInstance;
if (config === null || config === void 0 ? void 0 : config.componentProperties) {
component = Object.assign(component, config.componentProperties);
}
if (config.autoSpyOutputs) {
Object.keys(component).forEach((key) => {
const property = component[key];
if (property instanceof EventEmitter) {
component[key] = createOutputSpy(`${key}Spy`);
}
});
}
// Manually call ngOnChanges when mounting components using the class syntax.
// This is necessary because we are assigning input values to the class directly
// on mount and therefore the ngOnChanges() lifecycle is not triggered.
if (component.ngOnChanges && config.componentProperties) {
const { componentProperties } = config;
const simpleChanges = Object.entries(componentProperties).reduce((acc, [key, value]) => {
acc[key] = new SimpleChange(null, value, true);
return acc;
}, {});
if (Object.keys(componentProperties).length > 0) {
component.ngOnChanges(simpleChanges);
}
}
}
/**
* Mounts an Angular component inside Cypress browser
*
* @param component Angular component being mounted or its template
* @param config configuration used to configure the TestBed
* @example
* import { mount } from '@cypress/angular'
* import { StepperComponent } from './stepper.component'
* import { MyService } from 'services/my.service'
* import { SharedModule } from 'shared/shared.module';
* it('mounts', () => {
* mount(StepperComponent, {
* providers: [MyService],
* imports: [SharedModule]
* })
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* })
*
* // or
*
* it('mounts with template', () => {
* mount('<app-stepper></app-stepper>', {
* declarations: [StepperComponent],
* })
* })
*
* @see {@link https://on.cypress.io/mounting-angular} for more details.
*
* @returns A component and component fixture
*/
function mount(component, config = {}) {
// Remove last mounted component if cy.mount is called more than once in a test
if (activeFixture) {
cleanup();
}
const componentFixture = initTestBed(component, config);
activeFixture = setupFixture(componentFixture, config);
const mountResponse = {
fixture: activeFixture,
component: activeFixture.componentInstance,
};
const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name;
Cypress.log({
name: 'mount',
message: logMessage,
consoleProps: () => ({ result: mountResponse }),
});
return cy.wrap(mountResponse, { log: false });
}
/**
* Creates a new Event Emitter and then spies on it's `emit` method
*
* @param {string} alias name you want to use for your cy.spy() alias
* @returns EventEmitter<T>
* @example
* import { StepperComponent } from './stepper.component'
* import { mount, createOutputSpy } from '@cypress/angular'
*
* it('Has spy', () => {
* mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } })
* cy.get('[data-cy=increment]').click()
* cy.get('@changeSpy').should('have.been.called')
* })
*/
const createOutputSpy = (alias) => {
const emitter = new EventEmitter();
cy.spy(emitter, 'emit').as(alias);
return emitter;
};
// Only needs to run once, we reset before each test
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
teardown: { destroyAfterEach: false },
});
setupHooks(cleanup);
export { CypressTestComponentRenderer, createOutputSpy, mount };

View File

@ -0,0 +1,69 @@
{
"name": "@cypress/angular",
"version": "0.0.0-development",
"description": "Test Angular Components using Cypress",
"main": "dist/index.js",
"scripts": {
"prebuild": "rimraf dist",
"build": "rollup -c rollup.config.mjs",
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
"build-prod": "yarn build",
"check-ts": "tsc --noEmit",
"lint": "eslint --ext .js,.ts,.json, ."
},
"dependencies": {},
"devDependencies": {
"@angular/common": "^14.2.0",
"@angular/core": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0",
"@cypress/mount-utils": "0.0.0-development",
"typescript": "^4.7.4",
"zone.js": "~0.11.4"
},
"peerDependencies": {
"@angular/common": ">=13",
"@angular/core": ">=13",
"@angular/platform-browser-dynamic": ">=13",
"zone.js": ">=0.11.0"
},
"files": [
"dist"
],
"types": "dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/angular/#readme",
"author": "Jordan Powell",
"bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Fangular&template=1-bug-report.md&title=",
"keywords": [
"angular",
"cypress",
"cypress-io",
"test",
"testing"
],
"contributors": [
{
"name": "Jordan Powell",
"social": "@jordanpowell88"
},
{
"name": "Zach Williams",
"social": "@ZachJW34"
}
],
"module": "dist/index.js",
"publishConfig": {
"access": "public"
},
"standard": {
"globals": [
"Cypress",
"cy",
"expect"
]
}
}

3
CyLukTs/lukan/node_modules/cypress/bin/cypress generated vendored Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env node
require('../lib/cli').init()

27
CyLukTs/lukan/node_modules/cypress/index.js generated vendored Normal file
View File

@ -0,0 +1,27 @@
"use strict";
const minimist = require('minimist');
const debug = require('debug')('cypress:cli');
const args = minimist(process.argv.slice(2));
const util = require('./lib/util');
// we're being used from the command line
switch (args.exec) {
case 'install':
debug('installing Cypress from NPM');
require('./lib/tasks/install').start({
force: args.force
}).catch(util.logErrorExit1);
break;
case 'verify':
// for simple testing in the monorepo
debug('verifying Cypress');
require('./lib/tasks/verify').start({
force: true
}) // always force verification
.catch(util.logErrorExit1);
break;
default:
debug('exporting Cypress module interface');
module.exports = require('./lib/cypress');
}

17
CyLukTs/lukan/node_modules/cypress/index.mjs generated vendored Normal file
View File

@ -0,0 +1,17 @@
import module from 'module'
const require = module.createRequire(import.meta.url)
const cypress = require('./lib/cypress')
export default cypress
export const defineConfig = cypress.defineConfig
export const defineComponentFramework = cypress.defineComponentFramework
export const run = cypress.run
export const open = cypress.open
export const cli = cypress.cli

View File

@ -0,0 +1,58 @@
"use strict";
// Vendored from @cypress/listr-verbose-renderer
const figures = require('figures');
const cliCursor = require('cli-cursor');
const chalk = require('chalk');
const dayjs = require('dayjs');
const formattedLog = (options, output) => {
const timestamp = dayjs().format(options.dateFormat);
// eslint-disable-next-line no-console
console.log(`${chalk.dim(`[${timestamp}]`)} ${output}`);
};
const renderHelper = (task, event, options) => {
const log = formattedLog.bind(undefined, options);
if (event.type === 'STATE') {
const message = task.isPending() ? 'started' : task.state;
log(`${task.title} [${message}]`);
if (task.isSkipped() && task.output) {
log(`${figures.arrowRight} ${task.output}`);
}
} else if (event.type === 'TITLE') {
log(`${task.title} [title changed]`);
}
};
const render = (tasks, options) => {
for (const task of tasks) {
task.subscribe(event => {
if (event.type === 'SUBTASKS') {
render(task.subtasks, options);
return;
}
renderHelper(task, event, options);
}, err => {
// eslint-disable-next-line no-console
console.log(err);
});
}
};
class VerboseRenderer {
constructor(tasks, options) {
this._tasks = tasks;
this._options = Object.assign({
dateFormat: 'HH:mm:ss'
}, options);
}
static get nonTTY() {
return true;
}
render() {
cliCursor.hide();
render(this._tasks, this._options);
}
end() {
cliCursor.show();
}
}
module.exports = VerboseRenderer;

439
CyLukTs/lukan/node_modules/cypress/lib/cli.js generated vendored Normal file
View File

@ -0,0 +1,439 @@
"use strict";
// @ts-check
const _ = require('lodash');
const commander = require('commander');
const {
stripIndent
} = require('common-tags');
const logSymbols = require('log-symbols');
const debug = require('debug')('cypress:cli:cli');
const util = require('./util');
const logger = require('./logger');
const errors = require('./errors');
const cache = require('./tasks/cache');
// patch "commander" method called when a user passed an unknown option
// we want to print help for the current command and exit with an error
function unknownOption(flag, type = 'option') {
if (this._allowUnknownOption) return;
logger.error();
logger.error(` error: unknown ${type}:`, flag);
logger.error();
this.outputHelp();
util.exit(1);
}
commander.Command.prototype.unknownOption = unknownOption;
const coerceFalse = arg => {
return arg !== 'false';
};
const coerceAnyStringToInt = arg => {
return typeof arg === 'string' ? parseInt(arg) : arg;
};
const spaceDelimitedArgsMsg = (flag, args) => {
let msg = `
${logSymbols.warning} Warning: It looks like you're passing --${flag} a space-separated list of arguments:
"${args.join(' ')}"
This will work, but it's not recommended.
If you are trying to pass multiple arguments, separate them with commas instead:
cypress run --${flag} arg1,arg2,arg3
`;
if (flag === 'spec') {
msg += `
The most common cause of this warning is using an unescaped glob pattern. If you are
trying to pass a glob pattern, escape it using quotes:
cypress run --spec "**/*.spec.js"
`;
}
logger.log();
logger.warn(stripIndent(msg));
logger.log();
};
const parseVariableOpts = (fnArgs, args) => {
const [opts, unknownArgs] = fnArgs;
if (unknownArgs && unknownArgs.length && (opts.spec || opts.tag)) {
// this will capture space-delimited args after
// flags that could have possible multiple args
// but before the next option
// --spec spec1 spec2 or --tag foo bar
const multiArgFlags = _.compact([opts.spec ? 'spec' : opts.spec, opts.tag ? 'tag' : opts.tag]);
_.forEach(multiArgFlags, flag => {
const argIndex = _.indexOf(args, `--${flag}`) + 2;
const nextOptOffset = _.findIndex(_.slice(args, argIndex), arg => {
return _.startsWith(arg, '--');
});
const endIndex = nextOptOffset !== -1 ? argIndex + nextOptOffset : args.length;
const maybeArgs = _.slice(args, argIndex, endIndex);
const extraArgs = _.intersection(maybeArgs, unknownArgs);
if (extraArgs.length) {
opts[flag] = [opts[flag]].concat(extraArgs);
spaceDelimitedArgsMsg(flag, opts[flag]);
opts[flag] = opts[flag].join(',');
}
});
}
debug('variable-length opts parsed %o', {
args,
opts
});
return util.parseOpts(opts);
};
const descriptions = {
autoCancelAfterFailures: 'overrides the project-level Cloud configuration to set the failed test threshold for auto cancellation or to disable auto cancellation when recording to the Cloud',
browser: 'runs Cypress in the browser with the given name. if a filesystem path is supplied, Cypress will attempt to use the browser at that path.',
cacheClear: 'delete all cached binaries',
cachePrune: 'deletes all cached binaries except for the version currently in use',
cacheList: 'list cached binary versions',
cachePath: 'print the path to the binary cache',
cacheSize: 'Used with the list command to show the sizes of the cached folders',
ciBuildId: 'the unique identifier for a run on your CI provider. typically a "BUILD_ID" env var. this value is automatically detected for most CI providers',
component: 'runs component tests',
config: 'sets configuration values. separate multiple values with a comma. overrides any value in cypress.config.{js,ts,mjs,cjs}.',
configFile: 'path to script file where configuration values are set. defaults to "cypress.config.{js,ts,mjs,cjs}".',
detached: 'runs Cypress application in detached mode',
dev: 'runs cypress in development and bypasses binary check',
e2e: 'runs end to end tests',
env: 'sets environment variables. separate multiple values with a comma. overrides any value in cypress.config.{js,ts,mjs,cjs} or cypress.env.json',
exit: 'keep the browser open after tests finish',
forceInstall: 'force install the Cypress binary',
global: 'force Cypress into global mode as if its globally installed',
group: 'a named group for recorded runs in Cypress Cloud',
headed: 'displays the browser instead of running headlessly',
headless: 'hide the browser instead of running headed (default for cypress run)',
key: 'your secret Record Key. you can omit this if you set a CYPRESS_RECORD_KEY environment variable.',
parallel: 'enables concurrent runs and automatic load balancing of specs across multiple machines or processes',
port: 'runs Cypress on a specific port. overrides any value in cypress.config.{js,ts,mjs,cjs}.',
project: 'path to the project',
quiet: 'run quietly, using only the configured reporter',
record: 'records the run. sends test results, screenshots and videos to Cypress Cloud.',
reporter: 'runs a specific mocha reporter. pass a path to use a custom reporter. defaults to "spec"',
reporterOptions: 'options for the mocha reporter. defaults to "null"',
spec: 'runs specific spec file(s). defaults to "all"',
tag: 'named tag(s) for recorded runs in Cypress Cloud',
version: 'prints Cypress version'
};
const knownCommands = ['cache', 'help', '-h', '--help', 'install', 'open', 'run', 'open-ct', 'run-ct', 'verify', '-v', '--version', 'version', 'info'];
const text = description => {
if (!descriptions[description]) {
throw new Error(`Could not find description for: ${description}`);
}
return descriptions[description];
};
function includesVersion(args) {
return _.includes(args, '--version') || _.includes(args, '-v');
}
function showVersions(opts) {
debug('printing Cypress version');
debug('additional arguments %o', opts);
debug('parsed version arguments %o', opts);
const reportAllVersions = versions => {
logger.always('Cypress package version:', versions.package);
logger.always('Cypress binary version:', versions.binary);
logger.always('Electron version:', versions.electronVersion);
logger.always('Bundled Node version:', versions.electronNodeVersion);
};
const reportComponentVersion = (componentName, versions) => {
const names = {
package: 'package',
binary: 'binary',
electron: 'electronVersion',
node: 'electronNodeVersion'
};
if (!names[componentName]) {
throw new Error(`Unknown component name "${componentName}"`);
}
const name = names[componentName];
if (!versions[name]) {
throw new Error(`Cannot find version for component "${componentName}" under property "${name}"`);
}
const version = versions[name];
logger.always(version);
};
const defaultVersions = {
package: undefined,
binary: undefined,
electronVersion: undefined,
electronNodeVersion: undefined
};
return require('./exec/versions').getVersions().then((versions = defaultVersions) => {
if (opts !== null && opts !== void 0 && opts.component) {
reportComponentVersion(opts.component, versions);
} else {
reportAllVersions(versions);
}
process.exit(0);
}).catch(util.logErrorExit1);
}
const createProgram = () => {
const program = new commander.Command();
// bug in commander not printing name
// in usage help docs
program._name = 'cypress';
program.usage('<command> [options]');
return program;
};
const addCypressRunCommand = program => {
return program.command('run').usage('[options]').description('Runs Cypress tests from the CLI without the GUI').option('--auto-cancel-after-failures <test-failure-count || false>', text('autoCancelAfterFailures')).option('-b, --browser <browser-name-or-path>', text('browser')).option('--ci-build-id <id>', text('ciBuildId')).option('--component', text('component')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('--e2e', text('e2e')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse);
};
const addCypressOpenCommand = program => {
return program.command('open').usage('[options]').description('Opens Cypress in the interactive GUI.').option('-b, --browser <browser-path>', text('browser')).option('--component', text('component')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('--e2e', text('e2e')).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse);
};
const maybeAddInspectFlags = program => {
if (process.argv.includes('--dev')) {
return program.option('--inspect', 'Node option').option('--inspect-brk', 'Node option');
}
return program;
};
/**
* Casts known command line options for "cypress run" to their intended type.
* For example if the user passes "--port 5005" the ".port" property should be
* a number 5005 and not a string "5005".
*
* Returns a clone of the original object.
*/
const castCypressOptions = opts => {
// only properties that have type "string | false" in our TS definition
// require special handling, because CLI parsing takes care of purely
// boolean arguments
const castOpts = {
...opts
};
if (_.has(opts, 'port')) {
castOpts.port = coerceAnyStringToInt(opts.port);
}
return castOpts;
};
module.exports = {
/**
* Parses `cypress run` command line option array into an object
* with options that you can feed into a `cypress.run()` module API call.
* @example
* const options = parseRunCommand(['cypress', 'run', '--browser', 'chrome'])
* // options is {browser: 'chrome'}
*/
parseRunCommand(args) {
return new Promise((resolve, reject) => {
if (!Array.isArray(args)) {
return reject(new Error('Expected array of arguments'));
}
// make a copy of the input arguments array
// and add placeholders where "node ..." would usually be
// also remove "cypress" keyword at the start if present
const cliArgs = args[0] === 'cypress' ? [...args.slice(1)] : [...args];
cliArgs.unshift(null, null);
debug('creating program parser');
const program = createProgram();
maybeAddInspectFlags(addCypressRunCommand(program)).action((...fnArgs) => {
debug('parsed Cypress run %o', fnArgs);
const options = parseVariableOpts(fnArgs, cliArgs);
debug('parsed options %o', options);
const casted = castCypressOptions(options);
debug('casted options %o', casted);
resolve(casted);
});
debug('parsing args: %o', cliArgs);
program.parse(cliArgs);
});
},
/**
* Parses `cypress open` command line option array into an object
* with options that you can feed into cy.openModeSystemTest test calls
* @example
* const options = parseOpenCommand(['cypress', 'open', '--browser', 'chrome'])
* // options is {browser: 'chrome'}
*/
parseOpenCommand(args) {
return new Promise((resolve, reject) => {
if (!Array.isArray(args)) {
return reject(new Error('Expected array of arguments'));
}
// make a copy of the input arguments array
// and add placeholders where "node ..." would usually be
// also remove "cypress" keyword at the start if present
const cliArgs = args[0] === 'cypress' ? [...args.slice(1)] : [...args];
cliArgs.unshift(null, null);
debug('creating program parser');
const program = createProgram();
maybeAddInspectFlags(addCypressOpenCommand(program)).action((...fnArgs) => {
debug('parsed Cypress open %o', fnArgs);
const options = parseVariableOpts(fnArgs, cliArgs);
debug('parsed options %o', options);
const casted = castCypressOptions(options);
debug('casted options %o', casted);
resolve(casted);
});
debug('parsing args: %o', cliArgs);
program.parse(cliArgs);
});
},
/**
* Parses the command line and kicks off Cypress process.
*/
init(args) {
if (!args) {
args = process.argv;
}
const {
CYPRESS_INTERNAL_ENV,
CYPRESS_DOWNLOAD_USE_CA
} = process.env;
if (process.env.CYPRESS_DOWNLOAD_USE_CA) {
let msg = `
${logSymbols.warning} Warning: It looks like you're setting CYPRESS_DOWNLOAD_USE_CA=${CYPRESS_DOWNLOAD_USE_CA}
The environment variable "CYPRESS_DOWNLOAD_USE_CA" is no longer required to be set.
You can safely unset this environment variable.
`;
logger.log();
logger.warn(stripIndent(msg));
logger.log();
}
if (!util.isValidCypressInternalEnvValue(CYPRESS_INTERNAL_ENV)) {
debug('invalid CYPRESS_INTERNAL_ENV value', CYPRESS_INTERNAL_ENV);
return errors.exitWithError(errors.errors.invalidCypressEnv)(`CYPRESS_INTERNAL_ENV=${CYPRESS_INTERNAL_ENV}`);
}
if (util.isNonProductionCypressInternalEnvValue(CYPRESS_INTERNAL_ENV)) {
debug('non-production CYPRESS_INTERNAL_ENV value', CYPRESS_INTERNAL_ENV);
let msg = `
${logSymbols.warning} Warning: It looks like you're passing CYPRESS_INTERNAL_ENV=${CYPRESS_INTERNAL_ENV}
The environment variable "CYPRESS_INTERNAL_ENV" is reserved and should only be used internally.
Unset the "CYPRESS_INTERNAL_ENV" environment variable and run Cypress again.
`;
logger.log();
logger.warn(stripIndent(msg));
logger.log();
}
const program = createProgram();
program.command('help').description('Shows CLI help and exits').action(() => {
program.help();
});
const handleVersion = cmd => {
return cmd.option('--component <package|binary|electron|node>', 'component to report version for').action((opts, ...other) => {
showVersions(util.parseOpts(opts));
});
};
handleVersion(program.storeOptionsAsProperties().option('-v, --version', text('version')).command('version').description(text('version')));
maybeAddInspectFlags(addCypressOpenCommand(program)).action(opts => {
debug('opening Cypress');
require('./exec/open').start(util.parseOpts(opts)).then(util.exit).catch(util.logErrorExit1);
});
maybeAddInspectFlags(addCypressRunCommand(program)).action((...fnArgs) => {
debug('running Cypress with args %o', fnArgs);
require('./exec/run').start(parseVariableOpts(fnArgs, args)).then(util.exit).catch(util.logErrorExit1);
});
program.command('open-ct').usage('[options]').description('Opens Cypress component testing interactive mode. Deprecated: use "open --component"').option('-b, --browser <browser-path>', text('browser')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse).action(opts => {
debug('opening Cypress');
const msg = `
${logSymbols.warning} Warning: open-ct is deprecated and will be removed in a future release.
Use \`cypress open --component\` instead.
`;
logger.warn();
logger.warn(stripIndent(msg));
logger.warn();
require('./exec/open').start({
...util.parseOpts(opts),
testingType: 'component'
}).then(util.exit).catch(util.logErrorExit1);
});
program.command('run-ct').usage('[options]').description('Runs all Cypress component testing suites. Deprecated: use "run --component"').option('-b, --browser <browser-name-or-path>', text('browser')).option('--ci-build-id <id>', text('ciBuildId')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse).action(opts => {
debug('running Cypress run-ct');
const msg = `
${logSymbols.warning} Warning: run-ct is deprecated and will be removed in a future release.
Use \`cypress run --component\` instead.
`;
logger.warn();
logger.warn(stripIndent(msg));
logger.warn();
require('./exec/run').start({
...util.parseOpts(opts),
testingType: 'component'
}).then(util.exit).catch(util.logErrorExit1);
});
program.command('install').usage('[options]').description('Installs the Cypress executable matching this package\'s version').option('-f, --force', text('forceInstall')).action(opts => {
require('./tasks/install').start(util.parseOpts(opts)).catch(util.logErrorExit1);
});
program.command('verify').usage('[options]').description('Verifies that Cypress is installed correctly and executable').option('--dev', text('dev'), coerceFalse).action(opts => {
const defaultOpts = {
force: true,
welcomeMessage: false
};
const parsedOpts = util.parseOpts(opts);
const options = _.extend(parsedOpts, defaultOpts);
require('./tasks/verify').start(options).catch(util.logErrorExit1);
});
program.command('cache').usage('[command]').description('Manages the Cypress binary cache').option('list', text('cacheList')).option('path', text('cachePath')).option('clear', text('cacheClear')).option('prune', text('cachePrune')).option('--size', text('cacheSize')).action(function (opts, args) {
if (!args || !args.length) {
this.outputHelp();
util.exit(1);
}
const [command] = args;
if (!_.includes(['list', 'path', 'clear', 'prune'], command)) {
unknownOption.call(this, `cache ${command}`, 'command');
}
if (command === 'list') {
debug('cache command %o', {
command,
size: opts.size
});
return cache.list(opts.size).catch({
code: 'ENOENT'
}, () => {
logger.always('No cached binary versions were found.');
process.exit(0);
}).catch(e => {
debug('cache list command failed with "%s"', e.message);
util.logErrorExit1(e);
});
}
cache[command]();
});
program.command('info').usage('[command]').description('Prints Cypress and system information').option('--dev', text('dev'), coerceFalse).action(opts => {
require('./exec/info').start(opts).then(util.exit).catch(util.logErrorExit1);
});
debug('cli starts with arguments %j', args);
util.printNodeOptions();
// if there are no arguments
if (args.length <= 2) {
debug('printing help');
program.help();
// exits
}
const firstCommand = args[2];
if (!_.includes(knownCommands, firstCommand)) {
debug('unknown command %s', firstCommand);
logger.error('Unknown command', `"${firstCommand}"`);
program.outputHelp();
return util.exit(1);
}
if (includesVersion(args)) {
// commander 2.11.0 changes behavior
// and now does not understand top level options
// .option('-v, --version').command('version')
// so we have to manually catch '-v, --version'
handleVersion(program);
}
debug('program parsing arguments');
return program.parse(args);
}
};
// @ts-ignore
if (!module.parent) {
logger.error('This CLI module should be required from another Node module');
logger.error('and not executed directly');
process.exit(-1);
}

98
CyLukTs/lukan/node_modules/cypress/lib/cypress.js generated vendored Normal file
View File

@ -0,0 +1,98 @@
"use strict";
// https://github.com/cypress-io/cypress/issues/316
const Promise = require('bluebird');
const tmp = Promise.promisifyAll(require('tmp'));
const fs = require('./fs');
const open = require('./exec/open');
const run = require('./exec/run');
const util = require('./util');
const cli = require('./cli');
const cypressModuleApi = {
/**
* Opens Cypress GUI
* @see https://on.cypress.io/module-api#cypress-open
*/
open(options = {}) {
options = util.normalizeModuleOptions(options);
return open.start(options);
},
/**
* Runs Cypress tests in the current project
* @see https://on.cypress.io/module-api#cypress-run
*/
run(options = {}) {
if (!run.isValidProject(options.project)) {
return Promise.reject(new Error(`Invalid project path parameter: ${options.project}`));
}
options = util.normalizeModuleOptions(options);
tmp.setGracefulCleanup();
return tmp.fileAsync().then(outputPath => {
options.outputPath = outputPath;
return run.start(options).then(failedTests => {
return fs.readJsonAsync(outputPath, {
throws: false
}).then(output => {
if (!output) {
return {
status: 'failed',
failures: failedTests,
message: 'Could not find Cypress test run results'
};
}
return output;
});
});
});
},
cli: {
/**
* Parses CLI arguments into an object that you can pass to "cypress.run"
* @example
* const cypress = require('cypress')
* const cli = ['cypress', 'run', '--browser', 'firefox']
* const options = await cypress.cli.parseRunArguments(cli)
* // options is {browser: 'firefox'}
* await cypress.run(options)
* @see https://on.cypress.io/module-api
*/
parseRunArguments(args) {
return cli.parseRunCommand(args);
}
},
/**
* Provides automatic code completion for configuration in many popular code editors.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your config object with `defineConfig()`
* @example
* module.exports = defineConfig({
* viewportWith: 400
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ConfigOptions} config
* @returns {Cypress.ConfigOptions} the configuration passed in parameter
*/
defineConfig(config) {
return config;
},
/**
* Provides automatic code completion for Component Frameworks Definitions.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your Component Framework Definition object with `defineComponentFramework()`
* @example
* module.exports = defineComponentFramework({
* type: 'cypress-ct-solid-js'
* // ...
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ThirdPartyComponentFrameworkDefinition} config
* @returns {Cypress.ThirdPartyComponentFrameworkDefinition} the configuration passed in parameter
*/
defineComponentFramework(config) {
return config;
}
};
module.exports = cypressModuleApi;

392
CyLukTs/lukan/node_modules/cypress/lib/errors.js generated vendored Normal file
View File

@ -0,0 +1,392 @@
"use strict";
const chalk = require('chalk');
const {
stripIndent,
stripIndents
} = require('common-tags');
const la = require('lazy-ass');
const is = require('check-more-types');
const util = require('./util');
const state = require('./tasks/state');
const docsUrl = 'https://on.cypress.io';
const requiredDependenciesUrl = `${docsUrl}/required-dependencies`;
const runDocumentationUrl = `${docsUrl}/cypress-run`;
// TODO it would be nice if all error objects could be enforced via types
// to only have description + solution properties
const hr = '----------';
const genericErrorSolution = stripIndent`
Search for an existing issue or open a GitHub issue at
${chalk.blue(util.issuesUrl)}
`;
// common errors Cypress application can encounter
const unknownError = {
description: 'Unknown Cypress CLI error',
solution: genericErrorSolution
};
const invalidRunProjectPath = {
description: 'Invalid --project path',
solution: stripIndent`
Please provide a valid project path.
Learn more about ${chalk.cyan('cypress run')} at:
${chalk.blue(runDocumentationUrl)}
`
};
const invalidOS = {
description: 'The Cypress App could not be installed. Your machine does not meet the operating system requirements.',
solution: stripIndent`
${chalk.blue('https://on.cypress.io/guides/getting-started/installing-cypress#system-requirements')}`
};
const failedDownload = {
description: 'The Cypress App could not be downloaded.',
solution: stripIndent`
Does your workplace require a proxy to be used to access the Internet? If so, you must configure the HTTP_PROXY environment variable before downloading Cypress. Read more: https://on.cypress.io/proxy-configuration
Otherwise, please check network connectivity and try again:`
};
const failedUnzip = {
description: 'The Cypress App could not be unzipped.',
solution: genericErrorSolution
};
const failedUnzipWindowsMaxPathLength = {
description: 'The Cypress App could not be unzipped.',
solution: `This is most likely because the maximum path length is being exceeded on your system.
Read here for solutions to this problem: https://on.cypress.io/win-max-path-length-error`
};
const missingApp = binaryDir => {
return {
description: `No version of Cypress is installed in: ${chalk.cyan(binaryDir)}`,
solution: stripIndent`
\nPlease reinstall Cypress by running: ${chalk.cyan('cypress install')}
`
};
};
const binaryNotExecutable = executable => {
return {
description: `Cypress cannot run because this binary file does not have executable permissions here:\n\n${executable}`,
solution: stripIndent`\n
Reasons this may happen:
- node was installed as 'root' or with 'sudo'
- the cypress npm package as 'root' or with 'sudo'
Please check that you have the appropriate user permissions.
You can also try clearing the cache with 'cypress cache clear' and reinstalling.
`
};
};
const notInstalledCI = executable => {
return {
description: 'The cypress npm package is installed, but the Cypress binary is missing.',
solution: stripIndent`\n
We expected the binary to be installed here: ${chalk.cyan(executable)}
Reasons it may be missing:
- You're caching 'node_modules' but are not caching this path: ${util.getCacheDir()}
- You ran 'npm install' at an earlier build step but did not persist: ${util.getCacheDir()}
Properly caching the binary will fix this error and avoid downloading and unzipping Cypress.
Alternatively, you can run 'cypress install' to download the binary again.
${chalk.blue('https://on.cypress.io/not-installed-ci-error')}
`
};
};
const nonZeroExitCodeXvfb = {
description: 'Xvfb exited with a non zero exit code.',
solution: stripIndent`
There was a problem spawning Xvfb.
This is likely a problem with your system, permissions, or installation of Xvfb.
`
};
const missingXvfb = {
description: 'Your system is missing the dependency: Xvfb',
solution: stripIndent`
Install Xvfb and run Cypress again.
Read our documentation on dependencies for more information:
${chalk.blue(requiredDependenciesUrl)}
If you are using Docker, we provide containers with all required dependencies installed.
`
};
const smokeTestFailure = (smokeTestCommand, timedOut) => {
return {
description: `Cypress verification ${timedOut ? 'timed out' : 'failed'}.`,
solution: stripIndent`
This command failed with the following output:
${smokeTestCommand}
`
};
};
const invalidSmokeTestDisplayError = {
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR',
description: 'Cypress verification failed.',
solution(msg) {
return stripIndent`
Cypress failed to start after spawning a new Xvfb server.
The error logs we received were:
${hr}
${msg}
${hr}
This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
Please refer to the error above for more detail.
`;
}
};
const missingDependency = {
description: 'Cypress failed to start.',
// this message is too Linux specific
solution: stripIndent`
This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
Please refer to the error below for more details.
`
};
const invalidCacheDirectory = {
description: 'Cypress cannot write to the cache directory due to file permissions',
solution: stripIndent`
See discussion and possible solutions at
${chalk.blue(util.getGitHubIssueUrl(1281))}
`
};
const versionMismatch = {
description: 'Installed version does not match package version.',
solution: 'Install Cypress and verify app again'
};
const incompatibleHeadlessFlags = {
description: '`--headed` and `--headless` cannot both be passed.',
solution: 'Either pass `--headed` or `--headless`, but not both.'
};
const solutionUnknown = stripIndent`
Please search Cypress documentation for possible solutions:
${chalk.blue(docsUrl)}
Check if there is a GitHub issue describing this crash:
${chalk.blue(util.issuesUrl)}
Consider opening a new issue.
`;
const unexpected = {
description: 'An unexpected error occurred while verifying the Cypress executable.',
solution: solutionUnknown
};
const invalidCypressEnv = {
description: chalk.red('The environment variable with the reserved name "CYPRESS_INTERNAL_ENV" is set.'),
solution: chalk.red('Unset the "CYPRESS_INTERNAL_ENV" environment variable and run Cypress again.'),
exitCode: 11
};
const invalidTestingType = {
description: 'Invalid testingType',
solution: `Please provide a valid testingType. Valid test types are ${chalk.cyan('\'e2e\'')} and ${chalk.cyan('\'component\'')}.`
};
const incompatibleTestTypeFlags = {
description: '`--e2e` and `--component` cannot both be passed.',
solution: 'Either pass `--e2e` or `--component`, but not both.'
};
const incompatibleTestingTypeAndFlag = {
description: 'Set a `testingType` and also passed `--e2e` or `--component` flags.',
solution: 'Either set `testingType` or pass a testing type flag, but not both.'
};
const invalidConfigFile = {
description: '`--config-file` cannot be false.',
solution: 'Either pass a relative path to a valid Cypress config file or remove this option.'
};
/**
* This error happens when CLI detects that the child Test Runner process
* was killed with a signal, like SIGBUS
* @see https://github.com/cypress-io/cypress/issues/5808
* @param {'close'|'event'} eventName Child close event name
* @param {string} signal Signal that closed the child process, like "SIGBUS"
*/
const childProcessKilled = (eventName, signal) => {
return {
description: `The Test Runner unexpectedly exited via a ${chalk.cyan(eventName)} event with signal ${chalk.cyan(signal)}`,
solution: solutionUnknown
};
};
const CYPRESS_RUN_BINARY = {
notValid: value => {
const properFormat = `**/${state.getPlatformExecutable()}`;
return {
description: `Could not run binary set by environment variable: CYPRESS_RUN_BINARY=${value}`,
solution: `Ensure the environment variable is a path to the Cypress binary, matching ${properFormat}`
};
}
};
function addPlatformInformation(info) {
return util.getPlatformInfo().then(platform => {
return {
...info,
platform
};
});
}
/**
* Given an error object (see the errors above), forms error message text with details,
* then resolves with Error instance you can throw or reject with.
* @param {object} errorObject
* @returns {Promise<Error>} resolves with an Error
* @example
```js
// inside a Promise with "resolve" and "reject"
const errorObject = childProcessKilled('exit', 'SIGKILL')
return getError(errorObject).then(reject)
```
*/
function getError(errorObject) {
return formErrorText(errorObject).then(errorMessage => {
const err = new Error(errorMessage);
err.known = true;
return err;
});
}
/**
* Forms nice error message with error and platform information,
* and if possible a way to solve it. Resolves with a string.
*/
function formErrorText(info, msg, prevMessage) {
return addPlatformInformation(info).then(obj => {
const formatted = [];
function add(msg) {
formatted.push(stripIndents(msg));
}
la(is.unemptyString(obj.description), 'expected error description to be text', obj.description);
// assuming that if there the solution is a function it will handle
// error message and (optional previous error message)
if (is.fn(obj.solution)) {
const text = obj.solution(msg, prevMessage);
la(is.unemptyString(text), 'expected solution to be text', text);
add(`
${obj.description}
${text}
`);
} else {
la(is.unemptyString(obj.solution), 'expected error solution to be text', obj.solution);
add(`
${obj.description}
${obj.solution}
`);
if (msg) {
add(`
${hr}
${msg}
`);
}
}
add(`
${hr}
${obj.platform}
`);
if (obj.footer) {
add(`
${hr}
${obj.footer}
`);
}
return formatted.join('\n\n');
});
}
const raise = info => {
return text => {
const err = new Error(text);
if (info.code) {
err.code = info.code;
}
err.known = true;
throw err;
};
};
const throwFormErrorText = info => {
return (msg, prevMessage) => {
return formErrorText(info, msg, prevMessage).then(raise(info));
};
};
/**
* Forms full error message with error and OS details, prints to the error output
* and then exits the process.
* @param {ErrorInformation} info Error information {description, solution}
* @example return exitWithError(errors.invalidCypressEnv)('foo')
*/
const exitWithError = info => {
return msg => {
return formErrorText(info, msg).then(text => {
// eslint-disable-next-line no-console
console.error(text);
process.exit(info.exitCode || 1);
});
};
};
module.exports = {
raise,
exitWithError,
// formError,
formErrorText,
throwFormErrorText,
getError,
hr,
errors: {
unknownError,
nonZeroExitCodeXvfb,
missingXvfb,
missingApp,
notInstalledCI,
missingDependency,
invalidOS,
invalidSmokeTestDisplayError,
versionMismatch,
binaryNotExecutable,
unexpected,
failedDownload,
failedUnzip,
failedUnzipWindowsMaxPathLength,
invalidCypressEnv,
invalidCacheDirectory,
CYPRESS_RUN_BINARY,
smokeTestFailure,
childProcessKilled,
incompatibleHeadlessFlags,
invalidRunProjectPath,
invalidTestingType,
incompatibleTestTypeFlags,
incompatibleTestingTypeAndFlag,
invalidConfigFile
}
};

92
CyLukTs/lukan/node_modules/cypress/lib/exec/info.js generated vendored Normal file
View File

@ -0,0 +1,92 @@
"use strict";
/* eslint-disable no-console */
const spawn = require('./spawn');
const util = require('../util');
const state = require('../tasks/state');
const os = require('os');
const chalk = require('chalk');
const prettyBytes = require('pretty-bytes');
const _ = require('lodash');
// color for numbers and show values
const g = chalk.green;
// color for paths
const p = chalk.cyan;
const red = chalk.red;
// urls
const link = chalk.blue.underline;
// to be exported
const methods = {};
methods.findProxyEnvironmentVariables = () => {
return _.pick(process.env, ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY']);
};
const maskSensitiveVariables = obj => {
const masked = {
...obj
};
if (masked.CYPRESS_RECORD_KEY) {
masked.CYPRESS_RECORD_KEY = '<redacted>';
}
return masked;
};
methods.findCypressEnvironmentVariables = () => {
const isCyVariable = (val, key) => key.startsWith('CYPRESS_');
return _.pickBy(process.env, isCyVariable);
};
const formatCypressVariables = () => {
const vars = methods.findCypressEnvironmentVariables();
return maskSensitiveVariables(vars);
};
methods.start = async (options = {}) => {
const args = ['--mode=info'];
await spawn.start(args, {
dev: options.dev
});
console.log();
const proxyVars = methods.findProxyEnvironmentVariables();
if (_.isEmpty(proxyVars)) {
console.log('Proxy Settings: none detected');
} else {
console.log('Proxy Settings:');
_.forEach(proxyVars, (value, key) => {
console.log('%s: %s', key, g(value));
});
console.log();
console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'));
console.log();
}
const cyVars = formatCypressVariables();
if (_.isEmpty(cyVars)) {
console.log('Environment Variables: none detected');
} else {
console.log('Environment Variables:');
_.forEach(cyVars, (value, key) => {
console.log('%s: %s', key, g(value));
});
}
console.log();
console.log('Application Data:', p(util.getApplicationDataFolder()));
console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')));
console.log('Binary Caches: %s', p(state.getCacheDir()));
console.log();
const osVersion = await util.getOsVersionAsync();
const buildInfo = util.pkgBuildInfo();
const isStable = buildInfo && buildInfo.stable;
console.log('Cypress Version: %s', g(util.pkgVersion()), isStable ? g('(stable)') : red('(pre-release)'));
console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion));
console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())));
if (!buildInfo) {
console.log();
console.log('This is the', red('development'), '(un-built) Cypress CLI.');
} else if (!isStable) {
console.log();
console.log('This is a', red('pre-release'), 'build of Cypress.');
console.log('Build info:');
console.log(' Commit SHA:', g(buildInfo.commitSha));
console.log(' Commit Branch:', g(buildInfo.commitBranch));
console.log(' Commit Date:', g(buildInfo.commitDate));
}
};
module.exports = methods;

90
CyLukTs/lukan/node_modules/cypress/lib/exec/open.js generated vendored Normal file
View File

@ -0,0 +1,90 @@
"use strict";
const debug = require('debug')('cypress:cli');
const util = require('../util');
const spawn = require('./spawn');
const verify = require('../tasks/verify');
const {
processTestingType,
checkConfigFile
} = require('./shared');
const {
exitWithError
} = require('../errors');
/**
* Maps options collected by the CLI
* and forms list of CLI arguments to the server.
*
* Note: there is lightweight validation, with errors
* thrown synchronously.
*
* @returns {string[]} list of CLI arguments
*/
const processOpenOptions = (options = {}) => {
// In addition to setting the project directory, setting the project option
// here ultimately decides whether cypress is run in global mode or not.
// It's first based off whether it's installed globally by npm/yarn (-g).
// A global install can be overridden by the --project flag, putting Cypress
// in project mode. A non-global install can be overridden by the --global
// flag, putting it in global mode.
if (!util.isInstalledGlobally() && !options.global && !options.project) {
options.project = process.cwd();
}
const args = [];
if (options.config) {
args.push('--config', options.config);
}
if (options.configFile !== undefined) {
checkConfigFile(options);
args.push('--config-file', options.configFile);
}
if (options.browser) {
args.push('--browser', options.browser);
}
if (options.env) {
args.push('--env', options.env);
}
if (options.port) {
args.push('--port', options.port);
}
if (options.project) {
args.push('--project', options.project);
}
if (options.global) {
args.push('--global', options.global);
}
if (options.inspect) {
args.push('--inspect');
}
if (options.inspectBrk) {
args.push('--inspectBrk');
}
args.push(...processTestingType(options));
debug('opening from options %j', options);
debug('command line arguments %j', args);
return args;
};
module.exports = {
processOpenOptions,
start(options = {}) {
function open() {
try {
const args = processOpenOptions(options);
return spawn.start(args, {
dev: options.dev,
detached: Boolean(options.detached)
});
} catch (err) {
if (err.details) {
return exitWithError(err.details)();
}
throw err;
}
}
if (options.dev) {
return open();
}
return verify.start().then(open);
}
};

173
CyLukTs/lukan/node_modules/cypress/lib/exec/run.js generated vendored Normal file
View File

@ -0,0 +1,173 @@
"use strict";
const _ = require('lodash');
const debug = require('debug')('cypress:cli:run');
const util = require('../util');
const spawn = require('./spawn');
const verify = require('../tasks/verify');
const {
exitWithError,
errors
} = require('../errors');
const {
processTestingType,
throwInvalidOptionError,
checkConfigFile
} = require('./shared');
/**
* Typically a user passes a string path to the project.
* But "cypress open" allows using `false` to open in global mode,
* and the user can accidentally execute `cypress run --project false`
* which should be invalid.
*/
const isValidProject = v => {
if (typeof v === 'boolean') {
return false;
}
if (v === '' || v === 'false' || v === 'true') {
return false;
}
return true;
};
/**
* Maps options collected by the CLI
* and forms list of CLI arguments to the server.
*
* Note: there is lightweight validation, with errors
* thrown synchronously.
*
* @returns {string[]} list of CLI arguments
*/
const processRunOptions = (options = {}) => {
debug('processing run options %o', options);
if (!isValidProject(options.project)) {
debug('invalid project option %o', {
project: options.project
});
return throwInvalidOptionError(errors.invalidRunProjectPath);
}
const args = ['--run-project', options.project];
if (options.autoCancelAfterFailures || options.autoCancelAfterFailures === 0 || options.autoCancelAfterFailures === false) {
args.push('--auto-cancel-after-failures', options.autoCancelAfterFailures);
}
if (options.browser) {
args.push('--browser', options.browser);
}
if (options.ciBuildId) {
args.push('--ci-build-id', options.ciBuildId);
}
if (options.config) {
args.push('--config', options.config);
}
if (options.configFile !== undefined) {
checkConfigFile(options);
args.push('--config-file', options.configFile);
}
if (options.env) {
args.push('--env', options.env);
}
if (options.exit === false) {
args.push('--no-exit');
}
if (options.group) {
args.push('--group', options.group);
}
if (options.headed) {
args.push('--headed', options.headed);
}
if (options.headless) {
if (options.headed) {
return throwInvalidOptionError(errors.incompatibleHeadlessFlags);
}
args.push('--headed', !options.headless);
}
// if key is set use that - else attempt to find it by environment variable
if (options.key == null) {
debug('--key is not set, looking up environment variable CYPRESS_RECORD_KEY');
options.key = util.getEnv('CYPRESS_RECORD_KEY');
}
// if we have a key assume we're in record mode
if (options.key) {
args.push('--key', options.key);
}
if (options.outputPath) {
args.push('--output-path', options.outputPath);
}
if (options.parallel) {
args.push('--parallel');
}
if (options.port) {
args.push('--port', options.port);
}
if (options.quiet) {
args.push('--quiet');
}
// if record is defined and we're not
// already in ci mode, then send it up
if (options.record != null) {
args.push('--record', options.record);
}
// if we have a specific reporter push that into the args
if (options.reporter) {
args.push('--reporter', options.reporter);
}
// if we have a specific reporter push that into the args
if (options.reporterOptions) {
args.push('--reporter-options', options.reporterOptions);
}
// if we have specific spec(s) push that into the args
if (options.spec) {
args.push('--spec', options.spec);
}
if (options.tag) {
args.push('--tag', options.tag);
}
if (options.inspect) {
args.push('--inspect');
}
if (options.inspectBrk) {
args.push('--inspectBrk');
}
args.push(...processTestingType(options));
return args;
};
module.exports = {
processRunOptions,
isValidProject,
// resolves with the number of failed tests
start(options = {}) {
_.defaults(options, {
key: null,
spec: null,
reporter: null,
reporterOptions: null,
project: process.cwd()
});
function run() {
try {
const args = processRunOptions(options);
debug('run to spawn.start args %j', args);
return spawn.start(args, {
dev: options.dev
});
} catch (err) {
if (err.details) {
return exitWithError(err.details)();
}
throw err;
}
}
if (options.dev) {
return run();
}
return verify.start().then(run);
}
};

62
CyLukTs/lukan/node_modules/cypress/lib/exec/shared.js generated vendored Normal file
View File

@ -0,0 +1,62 @@
"use strict";
const {
errors
} = require('../errors');
/**
* Throws an error with "details" property from
* "errors" object.
* @param {Object} details - Error details
*/
const throwInvalidOptionError = details => {
if (!details) {
details = errors.unknownError;
}
// throw this error synchronously, it will be caught later on and
// the details will be propagated to the promise chain
const err = new Error();
err.details = details;
throw err;
};
/**
* Selects exec args based on the configured `testingType`
* @param {string} testingType The type of tests being executed
* @returns {string[]} The array of new exec arguments
*/
const processTestingType = options => {
if (options.e2e && options.component) {
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
}
if (options.testingType && (options.component || options.e2e)) {
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
}
if (options.testingType === 'component' || options.component || options.ct) {
return ['--testing-type', 'component'];
}
if (options.testingType === 'e2e' || options.e2e) {
return ['--testing-type', 'e2e'];
}
if (options.testingType) {
return throwInvalidOptionError(errors.invalidTestingType);
}
return [];
};
/**
* Throws an error if configFile is string 'false' or boolean false
* @param {*} options
*/
const checkConfigFile = options => {
// CLI will parse as string, module API can pass in boolean
if (options.configFile === 'false' || options.configFile === false) {
throwInvalidOptionError(errors.invalidConfigFile);
}
};
module.exports = {
throwInvalidOptionError,
processTestingType,
checkConfigFile
};

289
CyLukTs/lukan/node_modules/cypress/lib/exec/spawn.js generated vendored Normal file
View File

@ -0,0 +1,289 @@
"use strict";
const _ = require('lodash');
const os = require('os');
const cp = require('child_process');
const path = require('path');
const Promise = require('bluebird');
const debug = require('debug')('cypress:cli');
const debugElectron = require('debug')('cypress:electron');
const util = require('../util');
const state = require('../tasks/state');
const xvfb = require('./xvfb');
const verify = require('../tasks/verify');
const errors = require('../errors');
const isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
const isHighSierraWarningRe = /\*\*\* WARNING/;
const isRenderWorkerRe = /\.RenderWorker-/;
// Chromium (which Electron uses) always makes several attempts to connect to the system dbus.
// This works fine in most desktop environments, but in a docker container, there is no dbus service
// and Chromium emits several error lines, similar to these:
// [1957:0406/160550.146820:ERROR:bus.cc(392)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
// [1957:0406/160550.147994:ERROR:bus.cc(392)] Failed to connect to the bus: Address does not contain a colon
// These warnings are absolutely harmless. Failure to connect to dbus means that electron won't be able to access the user's
// credential wallet (none exists in a docker container) and won't show up in the system tray (again, none exists).
// Failure to connect is expected and normal here, but users frequently misidentify these errors as the cause of their problems.
// https://github.com/cypress-io/cypress/issues/19299
const isDbusWarning = /Failed to connect to the bus:/;
// Electron began logging these on self-signed certs with 17.0.0-alpha.4.
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/34583
// Sample:
// [3801:0606/152837.383892:ERROR:cert_verify_proc_builtin.cc(681)] CertVerifyProcBuiltin for www.googletagmanager.com failed:
// ----- Certificate i=0 (OU=Cypress Proxy Server Certificate,O=Cypress Proxy CA,L=Internet,ST=Internet,C=Internet,CN=www.googletagmanager.com) -----
// ERROR: No matching issuer found
const isCertVerifyProcBuiltin = /(^\[.*ERROR:cert_verify_proc_builtin\.cc|^----- Certificate i=0 \(OU=Cypress Proxy|^ERROR: No matching issuer found$)/;
// Electron logs a benign warning about WebSwapCGLLayer on MacOS v12 and Electron v18 due to a naming collision in shared libraries.
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/33685
// Sample:
// objc[60540]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffa5a006318) and /{path/to/app}/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x10f8a89c8). One of the two will be used. Which one is undefined.
const isMacOSElectronWebSwapCGLLayerWarning = /^objc\[\d+\]: Class WebSwapCGLLayer is implemented in both.*Which one is undefined\./;
const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe, isDbusWarning, isCertVerifyProcBuiltin, isMacOSElectronWebSwapCGLLayerWarning];
const isGarbageLineWarning = str => {
return _.some(GARBAGE_WARNINGS, re => {
return re.test(str);
});
};
function isPlatform(platform) {
return os.platform() === platform;
}
function needsStderrPiped(needsXvfb) {
return _.some([isPlatform('darwin'), needsXvfb && isPlatform('linux'), util.isPossibleLinuxWithIncorrectDisplay()]);
}
function needsEverythingPipedDirectly() {
return isPlatform('win32');
}
function getStdio(needsXvfb) {
if (needsEverythingPipedDirectly()) {
return 'pipe';
}
// https://github.com/cypress-io/cypress/issues/921
// https://github.com/cypress-io/cypress/issues/1143
// https://github.com/cypress-io/cypress/issues/1745
if (needsStderrPiped(needsXvfb)) {
// returning pipe here so we can massage stderr
// and remove garbage from Xlib and libuv
// due to starting the Xvfb process on linux
return ['inherit', 'inherit', 'pipe'];
}
return 'inherit';
}
module.exports = {
isGarbageLineWarning,
start(args, options = {}) {
const needsXvfb = xvfb.isNeeded();
let executable = state.getPathToExecutable(state.getBinaryDir());
if (util.getEnv('CYPRESS_RUN_BINARY')) {
executable = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
}
debug('needs to start own Xvfb?', needsXvfb);
// Always push cwd into the args
// which additionally acts as a signal to the
// binary that it was invoked through the NPM module
args = args || [];
if (typeof args === 'string') {
args = [args];
}
args = [...args, '--cwd', process.cwd(), '--userNodePath', process.execPath, '--userNodeVersion', process.versions.node];
_.defaults(options, {
dev: false,
env: process.env,
detached: false,
stdio: getStdio(needsXvfb)
});
const spawn = (overrides = {}) => {
return new Promise((resolve, reject) => {
_.defaults(overrides, {
onStderrData: false,
electronLogging: false
});
const {
onStderrData,
electronLogging
} = overrides;
const envOverrides = util.getEnvOverrides(options);
const electronArgs = [];
const node11WindowsFix = isPlatform('win32');
let startScriptPath;
if (options.dev) {
executable = 'node';
// if we're in dev then reset
// the launch cmd to be 'npm run dev'
startScriptPath = path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'), debug('in dev mode the args became %o', args);
}
if (!options.dev && verify.needsSandbox()) {
electronArgs.push('--no-sandbox');
}
// strip dev out of child process options
/**
* @type {import('child_process').ForkOptions}
*/
let stdioOptions = _.pick(options, 'env', 'detached', 'stdio');
// figure out if we're going to be force enabling or disabling colors.
// also figure out whether we should force stdout and stderr into thinking
// it is a tty as opposed to a pipe.
stdioOptions.env = _.extend({}, stdioOptions.env, envOverrides);
if (node11WindowsFix) {
stdioOptions = _.extend({}, stdioOptions, {
windowsHide: false
});
}
if (electronLogging) {
stdioOptions.env.ELECTRON_ENABLE_LOGGING = true;
}
if (util.isPossibleLinuxWithIncorrectDisplay()) {
// make sure we use the latest DISPLAY variable if any
debug('passing DISPLAY', process.env.DISPLAY);
stdioOptions.env.DISPLAY = process.env.DISPLAY;
}
if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
// Since we are running electron as node, we need to add an entry point file.
startScriptPath = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
} else {
// Start arguments with "--" so Electron knows these are OUR
// arguments and does not try to sanitize them. Otherwise on Windows
// an url in one of the arguments crashes it :(
// https://github.com/cypress-io/cypress/issues/5466
args = [...electronArgs, '--', ...args];
}
if (startScriptPath) {
args.unshift(startScriptPath);
}
if (process.env.CYPRESS_INTERNAL_DEV_DEBUG) {
args.unshift(process.env.CYPRESS_INTERNAL_DEV_DEBUG);
}
debug('spawn args %o %o', args, _.omit(stdioOptions, 'env'));
debug('spawning Cypress with executable: %s', executable);
const child = cp.spawn(executable, args, stdioOptions);
function resolveOn(event) {
return function (code, signal) {
debug('child event fired %o', {
event,
code,
signal
});
if (code === null) {
const errorObject = errors.errors.childProcessKilled(event, signal);
return errors.getError(errorObject).then(reject);
}
resolve(code);
};
}
child.on('close', resolveOn('close'));
child.on('exit', resolveOn('exit'));
child.on('error', reject);
// if stdio options is set to 'pipe', then
// we should set up pipes:
// process STDIN (read stream) => child STDIN (writeable)
// child STDOUT => process STDOUT
// child STDERR => process STDERR with additional filtering
if (child.stdin) {
debug('piping process STDIN into child STDIN');
process.stdin.pipe(child.stdin);
}
if (child.stdout) {
debug('piping child STDOUT to process STDOUT');
child.stdout.pipe(process.stdout);
}
// if this is defined then we are manually piping for linux
// to filter out the garbage
if (child.stderr) {
debug('piping child STDERR to process STDERR');
child.stderr.on('data', data => {
const str = data.toString();
// bail if this is warning line garbage
if (isGarbageLineWarning(str)) {
return;
}
// if we have a callback and this explictly returns
// false then bail
if (onStderrData && onStderrData(str) === false) {
return;
}
// else pass it along!
process.stderr.write(data);
});
}
// https://github.com/cypress-io/cypress/issues/1841
// https://github.com/cypress-io/cypress/issues/5241
// In some versions of node, it will throw on windows
// when you close the parent process after piping
// into the child process. unpiping does not seem
// to have any effect. so we're just catching the
// error here and not doing anything.
process.stdin.on('error', err => {
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
return;
}
throw err;
});
if (stdioOptions.detached) {
child.unref();
}
});
};
const spawnInXvfb = () => {
return xvfb.start().then(userFriendlySpawn).finally(xvfb.stop);
};
const userFriendlySpawn = linuxWithDisplayEnv => {
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
let brokenGtkDisplay;
const overrides = {};
if (linuxWithDisplayEnv) {
_.extend(overrides, {
electronLogging: true,
onStderrData(str) {
// if we receive a broken pipe anywhere
// then we know that's why cypress exited early
if (util.isBrokenGtkDisplay(str)) {
brokenGtkDisplay = true;
}
// we should attempt to always slurp up
// the stderr logs unless we've explicitly
// enabled the electron debug logging
if (!debugElectron.enabled) {
return false;
}
}
});
}
return spawn(overrides).then(code => {
if (code !== 0 && brokenGtkDisplay) {
util.logBrokenGtkDisplayWarning();
return spawnInXvfb();
}
return code;
})
// we can format and handle an error message from the code above
// prevent wrapping error again by using "known: undefined" filter
.catch({
known: undefined
}, errors.throwFormErrorText(errors.errors.unexpected));
};
if (needsXvfb) {
return spawnInXvfb();
}
// if we are on linux and there's already a DISPLAY
// set, then we may need to rerun cypress after
// spawning our own Xvfb server
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
return userFriendlySpawn(linuxWithDisplayEnv);
}
};

View File

@ -0,0 +1,53 @@
"use strict";
const Promise = require('bluebird');
const debug = require('debug')('cypress:cli');
const path = require('path');
const util = require('../util');
const state = require('../tasks/state');
const {
throwFormErrorText,
errors
} = require('../errors');
const getVersions = () => {
return Promise.try(() => {
if (util.getEnv('CYPRESS_RUN_BINARY')) {
let envBinaryPath = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath).then(envBinaryDir => {
if (!envBinaryDir) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
}
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
return envBinaryDir;
}).catch({
code: 'ENOENT'
}, err => {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
});
}
return state.getBinaryDir();
}).then(state.getBinaryPkgAsync).then(pkg => {
const versions = {
binary: state.getBinaryPkgVersion(pkg),
electronVersion: state.getBinaryElectronVersion(pkg),
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg)
};
debug('binary versions %o', versions);
return versions;
}).then(binaryVersions => {
const buildInfo = util.pkgBuildInfo();
let packageVersion = util.pkgVersion();
if (!buildInfo) packageVersion += ' (development)';else if (!buildInfo.stable) packageVersion += ' (pre-release)';
const versions = {
package: packageVersion,
binary: binaryVersions.binary || 'not installed',
electronVersion: binaryVersions.electronVersion || 'not found',
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found'
};
debug('combined versions %o', versions);
return versions;
});
};
module.exports = {
getVersions
};

94
CyLukTs/lukan/node_modules/cypress/lib/exec/xvfb.js generated vendored Normal file
View File

@ -0,0 +1,94 @@
"use strict";
const os = require('os');
const Promise = require('bluebird');
const Xvfb = require('@cypress/xvfb');
const {
stripIndent
} = require('common-tags');
const Debug = require('debug');
const {
throwFormErrorText,
errors
} = require('../errors');
const util = require('../util');
const debug = Debug('cypress:cli');
const debugXvfb = Debug('cypress:xvfb');
debug.Debug = debugXvfb.Debug = Debug;
const xvfbOptions = {
displayNum: process.env.XVFB_DISPLAY_NUM,
timeout: 30000,
// milliseconds
// need to explicitly define screen otherwise electron will crash
// https://github.com/cypress-io/cypress/issues/6184
xvfb_args: ['-screen', '0', '1280x1024x24'],
onStderrData(data) {
if (debugXvfb.enabled) {
debugXvfb(data.toString());
}
}
};
const xvfb = Promise.promisifyAll(new Xvfb(xvfbOptions));
module.exports = {
_debugXvfb: debugXvfb,
// expose for testing
_xvfb: xvfb,
// expose for testing
_xvfbOptions: xvfbOptions,
// expose for testing
start() {
debug('Starting Xvfb');
return xvfb.startAsync().return(null).catch({
nonZeroExitCode: true
}, throwFormErrorText(errors.nonZeroExitCodeXvfb)).catch(err => {
if (err.known) {
throw err;
}
return throwFormErrorText(errors.missingXvfb)(err);
});
},
stop() {
debug('Stopping Xvfb');
return xvfb.stopAsync().return(null).catch(() => {
// noop
});
},
isNeeded() {
if (process.env.ELECTRON_RUN_AS_NODE) {
debug('Environment variable ELECTRON_RUN_AS_NODE detected, xvfb is not needed');
return false; // xvfb required for electron processes only.
}
if (os.platform() !== 'linux') {
return false;
}
if (process.env.DISPLAY) {
const issueUrl = util.getGitHubIssueUrl(4034);
const message = stripIndent`
DISPLAY environment variable is set to ${process.env.DISPLAY} on Linux
Assuming this DISPLAY points at working X11 server,
Cypress will not spawn own Xvfb
NOTE: if the X11 server is NOT working, Cypress will exit without explanation,
see ${issueUrl}
Solution: Unset the DISPLAY variable and try again:
DISPLAY= npx cypress run ...
`;
debug(message);
return false;
}
debug('undefined DISPLAY environment variable');
debug('Cypress will spawn its own Xvfb');
return true;
},
// async method, resolved with Boolean
verify() {
return xvfb.startAsync().return(true).catch(err => {
debug('Could not verify xvfb: %s', err.message);
return false;
}).finally(xvfb.stopAsync);
}
};

4
CyLukTs/lukan/node_modules/cypress/lib/fs.js generated vendored Normal file
View File

@ -0,0 +1,4 @@
"use strict";
const Promise = require('bluebird');
module.exports = Promise.promisifyAll(require('fs-extra'));

53
CyLukTs/lukan/node_modules/cypress/lib/logger.js generated vendored Normal file
View File

@ -0,0 +1,53 @@
"use strict";
const chalk = require('chalk');
let logs = [];
const logLevel = () => {
return process.env.npm_config_loglevel || 'notice';
};
const error = (...messages) => {
logs.push(messages.join(' '));
console.log(chalk.red(...messages)); // eslint-disable-line no-console
};
const warn = (...messages) => {
if (logLevel() === 'silent') return;
logs.push(messages.join(' '));
console.log(chalk.yellow(...messages)); // eslint-disable-line no-console
};
const log = (...messages) => {
if (logLevel() === 'silent' || logLevel() === 'warn') return;
logs.push(messages.join(' '));
console.log(...messages); // eslint-disable-line no-console
};
const always = (...messages) => {
logs.push(messages.join(' '));
console.log(...messages); // eslint-disable-line no-console
};
// splits long text into lines and calls log()
// on each one to allow easy unit testing for specific message
const logLines = text => {
const lines = text.split('\n');
for (const line of lines) {
log(line);
}
};
const print = () => {
return logs.join('\n');
};
const reset = () => {
logs = [];
};
module.exports = {
log,
warn,
error,
always,
logLines,
print,
reset,
logLevel
};

132
CyLukTs/lukan/node_modules/cypress/lib/tasks/cache.js generated vendored Normal file
View File

@ -0,0 +1,132 @@
"use strict";
const state = require('./state');
const logger = require('../logger');
const fs = require('../fs');
const util = require('../util');
const {
join
} = require('path');
const Table = require('cli-table3');
const dayjs = require('dayjs');
const relativeTime = require('dayjs/plugin/relativeTime');
const chalk = require('chalk');
const _ = require('lodash');
const getFolderSize = require('./get-folder-size');
const Bluebird = require('bluebird');
dayjs.extend(relativeTime);
// output colors for the table
const colors = {
titles: chalk.white,
dates: chalk.cyan,
values: chalk.green,
size: chalk.gray
};
const logCachePath = () => {
logger.always(state.getCacheDir());
return undefined;
};
const clear = () => {
return fs.removeAsync(state.getCacheDir());
};
const prune = () => {
const cacheDir = state.getCacheDir();
const checkedInBinaryVersion = util.pkgVersion();
let deletedBinary = false;
return fs.readdirAsync(cacheDir).then(versions => {
return Bluebird.all(versions.map(version => {
if (version !== checkedInBinaryVersion) {
deletedBinary = true;
const versionDir = join(cacheDir, version);
return fs.removeAsync(versionDir);
}
}));
}).then(() => {
if (deletedBinary) {
logger.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`);
} else {
logger.always(`No binary caches found to prune.`);
}
}).catch({
code: 'ENOENT'
}, () => {
logger.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
});
};
const fileSizeInMB = size => {
return `${(size / 1024 / 1024).toFixed(1)}MB`;
};
/**
* Collects all cached versions, finds when each was used
* and prints a table with results to the terminal
*/
const list = showSize => {
return getCachedVersions(showSize).then(binaries => {
const head = [colors.titles('version'), colors.titles('last used')];
if (showSize) {
head.push(colors.titles('size'));
}
const table = new Table({
head
});
binaries.forEach(binary => {
const versionString = colors.values(binary.version);
const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
const row = [versionString, lastUsed];
if (showSize) {
const size = colors.size(fileSizeInMB(binary.size));
row.push(size);
}
return table.push(row);
});
logger.always(table.toString());
});
};
const getCachedVersions = showSize => {
const cacheDir = state.getCacheDir();
return fs.readdirAsync(cacheDir).filter(util.isSemver).map(version => {
return {
version,
folderPath: join(cacheDir, version)
};
}).mapSeries(binary => {
// last access time on the folder is different from last access time
// on the Cypress binary
const binaryDir = state.getBinaryDir(binary.version);
const executable = state.getPathToExecutable(binaryDir);
return fs.statAsync(executable).then(stat => {
const lastAccessedTime = _.get(stat, 'atime');
if (!lastAccessedTime) {
// the test runner has never been opened
// or could be a test simulating missing timestamp
return binary;
}
const accessed = dayjs(lastAccessedTime).fromNow();
binary.accessed = accessed;
return binary;
}, e => {
// could not find the binary or gets its stats
return binary;
});
}).mapSeries(binary => {
if (showSize) {
const binaryDir = state.getBinaryDir(binary.version);
return getFolderSize(binaryDir).then(size => {
return {
...binary,
size
};
});
}
return binary;
});
};
module.exports = {
path: logCachePath,
clear,
prune,
list,
getCachedVersions
};

View File

@ -0,0 +1,319 @@
"use strict";
const la = require('lazy-ass');
const is = require('check-more-types');
const os = require('os');
const url = require('url');
const path = require('path');
const debug = require('debug')('cypress:cli');
const request = require('@cypress/request');
const Promise = require('bluebird');
const requestProgress = require('request-progress');
const {
stripIndent
} = require('common-tags');
const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
const {
throwFormErrorText,
errors
} = require('../errors');
const fs = require('../fs');
const util = require('../util');
const defaultBaseUrl = 'https://download.cypress.io/';
const defaultMaxRedirects = 10;
const getProxyForUrlWithNpmConfig = url => {
return getProxyForUrl(url) || process.env.npm_config_https_proxy || process.env.npm_config_proxy || null;
};
const getBaseUrl = () => {
if (util.getEnv('CYPRESS_DOWNLOAD_MIRROR')) {
let baseUrl = util.getEnv('CYPRESS_DOWNLOAD_MIRROR');
if (!baseUrl.endsWith('/')) {
baseUrl += '/';
}
return baseUrl;
}
return defaultBaseUrl;
};
const getCA = () => {
return new Promise(resolve => {
if (process.env.npm_config_cafile) {
fs.readFile(process.env.npm_config_cafile, 'utf8').then(cafileContent => {
resolve(cafileContent);
}).catch(() => {
resolve();
});
} else if (process.env.npm_config_ca) {
resolve(process.env.npm_config_ca);
} else {
resolve();
}
});
};
const prepend = (arch, urlPath, version) => {
const endpoint = url.resolve(getBaseUrl(), urlPath);
const platform = os.platform();
const pathTemplate = util.getEnv('CYPRESS_DOWNLOAD_PATH_TEMPLATE', true);
return pathTemplate ? pathTemplate.replace(/\\?\$\{endpoint\}/g, endpoint).replace(/\\?\$\{platform\}/g, platform).replace(/\\?\$\{arch\}/g, arch).replace(/\\?\$\{version\}/g, version) : `${endpoint}?platform=${platform}&arch=${arch}`;
};
const getUrl = (arch, version) => {
if (is.url(version)) {
debug('version is already an url', version);
return version;
}
const urlPath = version ? `desktop/${version}` : 'desktop';
return prepend(arch, urlPath, version);
};
const statusMessage = err => {
return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString();
};
const prettyDownloadErr = (err, url) => {
const msg = stripIndent`
URL: ${url}
${statusMessage(err)}
`;
debug(msg);
return throwFormErrorText(errors.failedDownload)(msg);
};
/**
* Checks checksum and file size for the given file. Allows both
* values or just one of them to be checked.
*/
const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
if (expectedSize && expectedChecksum) {
debug('verifying checksum and file size');
return Promise.join(util.getFileChecksum(filename), util.getFileSize(filename), (checksum, filesize) => {
if (checksum === expectedChecksum && filesize === expectedSize) {
debug('downloaded file has the expected checksum and size ✅');
return;
}
debug('raising error: checksum or file size mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have checksum: ${expectedChecksum}
Computed checksum: ${checksum}
Expected downloaded file to have size: ${expectedSize}
Computed size: ${filesize}
`;
debug(text);
throw new Error(text);
});
}
if (expectedChecksum) {
debug('only checking expected file checksum %d', expectedChecksum);
return util.getFileChecksum(filename).then(checksum => {
if (checksum === expectedChecksum) {
debug('downloaded file has the expected checksum ✅');
return;
}
debug('raising error: file checksum mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have checksum: ${expectedChecksum}
Computed checksum: ${checksum}
`;
throw new Error(text);
});
}
if (expectedSize) {
// maybe we don't have a checksum, but at least CDN returns content length
// which we can check against the file size
debug('only checking expected file size %d', expectedSize);
return util.getFileSize(filename).then(filesize => {
if (filesize === expectedSize) {
debug('downloaded file has the expected size ✅');
return;
}
debug('raising error: file size mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have size: ${expectedSize}
Computed size: ${filesize}
`;
throw new Error(text);
});
}
debug('downloaded file lacks checksum or size to verify');
return Promise.resolve();
};
// downloads from given url
// return an object with
// {filename: ..., downloaded: true}
const downloadFromUrl = ({
url,
downloadDestination,
progress,
ca,
version,
redirectTTL = defaultMaxRedirects
}) => {
if (redirectTTL <= 0) {
return Promise.reject(new Error(stripIndent`
Failed downloading the Cypress binary.
There were too many redirects. The default allowance is ${defaultMaxRedirects}.
Maybe you got stuck in a redirect loop?
`));
}
return new Promise((resolve, reject) => {
const proxy = getProxyForUrlWithNpmConfig(url);
debug('Downloading package', {
url,
proxy,
downloadDestination
});
if (ca) {
debug('using custom CA details from npm config');
}
const reqOptions = {
uri: url,
...(proxy ? {
proxy
} : {}),
...(ca ? {
agentOptions: {
ca
}
} : {}),
method: 'GET',
followRedirect: false
};
const req = request(reqOptions);
// closure
let started = null;
let expectedSize;
let expectedChecksum;
requestProgress(req, {
throttle: progress.throttle
}).on('response', response => {
// we have computed checksum and filesize during test runner binary build
// and have set it on the S3 object as user meta data, available via
// these custom headers "x-amz-meta-..."
// see https://github.com/cypress-io/cypress/pull/4092
expectedSize = response.headers['x-amz-meta-size'] || response.headers['content-length'];
expectedChecksum = response.headers['x-amz-meta-checksum'];
if (expectedChecksum) {
debug('expected checksum %s', expectedChecksum);
}
if (expectedSize) {
// convert from string (all Amazon custom headers are strings)
expectedSize = Number(expectedSize);
debug('expected file size %d', expectedSize);
}
// start counting now once we've gotten
// response headers
started = new Date();
if (/^3/.test(response.statusCode)) {
const redirectVersion = response.headers['x-version'];
const redirectUrl = response.headers.location;
debug('redirect version:', redirectVersion);
debug('redirect url:', redirectUrl);
downloadFromUrl({
url: redirectUrl,
progress,
ca,
downloadDestination,
version: redirectVersion,
redirectTTL: redirectTTL - 1
}).then(resolve).catch(reject);
// if our status code does not start with 200
} else if (!/^2/.test(response.statusCode)) {
debug('response code %d', response.statusCode);
const err = new Error(stripIndent`
Failed downloading the Cypress binary.
Response code: ${response.statusCode}
Response message: ${response.statusMessage}
`);
reject(err);
// status codes here are all 2xx
} else {
// We only enable this pipe connection when we know we've got a successful return
// and handle the completion with verify and resolve
// there was a possible race condition between end of request and close of writeStream
// that is made ordered with this Promise.all
Promise.all([new Promise(r => {
return response.pipe(fs.createWriteStream(downloadDestination).on('close', r));
}), new Promise(r => response.on('end', r))]).then(() => {
debug('downloading finished');
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(() => debug('verified')).then(() => resolve(version)).catch(reject);
});
}
}).on('error', e => {
if (e.code === 'ECONNRESET') return; // sometimes proxies give ECONNRESET but we don't care
reject(e);
}).on('progress', state => {
// total time we've elapsed
// starting on our first progress notification
const elapsed = new Date() - started;
// request-progress sends a value between 0 and 1
const percentage = util.convertPercentToPercentage(state.percent);
const eta = util.calculateEta(percentage, elapsed);
// send up our percent and seconds remaining
progress.onProgress(percentage, util.secsRemaining(eta));
});
});
};
/**
* Download Cypress.zip from external versionUrl to local file.
* @param [string] version Could be "3.3.0" or full URL
* @param [string] downloadDestination Local filename to save as
*/
const start = async opts => {
let {
version,
downloadDestination,
progress,
redirectTTL
} = opts;
if (!downloadDestination) {
la(is.unemptyString(downloadDestination), 'missing download dir', opts);
}
if (!progress) {
progress = {
onProgress: () => {
return {};
}
};
}
const arch = await util.getRealArch();
const versionUrl = getUrl(arch, version);
progress.throttle = 100;
debug('needed Cypress version: %s', version);
debug('source url %s', versionUrl);
debug(`downloading cypress.zip to "${downloadDestination}"`);
// ensure download dir exists
return fs.ensureDirAsync(path.dirname(downloadDestination)).then(() => {
return getCA();
}).then(ca => {
return downloadFromUrl({
url: versionUrl,
downloadDestination,
progress,
ca,
version,
...(redirectTTL ? {
redirectTTL
} : {})
});
}).catch(err => {
return prettyDownloadErr(err, versionUrl);
});
};
module.exports = {
start,
getUrl,
getProxyForUrlWithNpmConfig,
getCA
};

View File

@ -0,0 +1,33 @@
"use strict";
const fs = require('../fs');
const {
join
} = require('path');
const Bluebird = require('bluebird');
/**
* Get the size of a folder or a file.
*
* This function returns the actual file size of the folder (size), not the allocated space on disk (size on disk).
* For more details between the difference, check this link:
* https://www.howtogeek.com/180369/why-is-there-a-big-difference-between-size-and-size-on-disk/
*
* @param {string} path path to the file or the folder.
*/
async function getSize(path) {
const stat = await fs.lstat(path);
if (stat.isDirectory()) {
const list = await fs.readdir(path);
return Bluebird.resolve(list).reduce(async (prev, curr) => {
const currPath = join(path, curr);
const s = await fs.lstat(currPath);
if (s.isDirectory()) {
return prev + (await getSize(currPath));
}
return prev + s.size;
}, 0);
}
return stat.size;
}
module.exports = getSize;

360
CyLukTs/lukan/node_modules/cypress/lib/tasks/install.js generated vendored Normal file
View File

@ -0,0 +1,360 @@
"use strict";
const _ = require('lodash');
const os = require('os');
const path = require('path');
const chalk = require('chalk');
const debug = require('debug')('cypress:cli');
const {
Listr
} = require('listr2');
const Promise = require('bluebird');
const logSymbols = require('log-symbols');
const {
stripIndent
} = require('common-tags');
const fs = require('../fs');
const download = require('./download');
const util = require('../util');
const state = require('./state');
const unzip = require('./unzip');
const logger = require('../logger');
const {
throwFormErrorText,
errors
} = require('../errors');
const verbose = require('../VerboseRenderer');
const {
buildInfo,
version
} = require('../../package.json');
function _getBinaryUrlFromBuildInfo(arch, {
commitSha,
commitBranch
}) {
return `https://cdn.cypress.io/beta/binary/${version}/${os.platform()}-${arch}/${commitBranch}-${commitSha}/cypress.zip`;
}
const alreadyInstalledMsg = () => {
if (!util.isPostInstall()) {
logger.log(stripIndent`
Skipping installation:
Pass the ${chalk.yellow('--force')} option if you'd like to reinstall anyway.
`);
}
};
const displayCompletionMsg = () => {
// check here to see if we are globally installed
if (util.isInstalledGlobally()) {
// if we are display a warning
logger.log();
logger.warn(stripIndent`
${logSymbols.warning} Warning: It looks like you\'ve installed Cypress globally.
This will work, but it'\s not recommended.
The recommended way to install Cypress is as a devDependency per project.
You should probably run these commands:
- ${chalk.cyan('npm uninstall -g cypress')}
- ${chalk.cyan('npm install --save-dev cypress')}
`);
return;
}
logger.log();
logger.log('You can now open Cypress by running:', chalk.cyan(path.join('node_modules', '.bin', 'cypress'), 'open'));
logger.log();
logger.log(chalk.grey('https://on.cypress.io/installing-cypress'));
logger.log();
};
const downloadAndUnzip = ({
version,
installDir,
downloadDir
}) => {
const progress = {
throttle: 100,
onProgress: null
};
const downloadDestination = path.join(downloadDir, `cypress-${process.pid}.zip`);
const rendererOptions = getRendererOptions();
// let the user know what version of cypress we're downloading!
logger.log(`Installing Cypress ${chalk.gray(`(version: ${version})`)}`);
logger.log();
const tasks = new Listr([{
options: {
title: util.titleize('Downloading Cypress')
},
task: (ctx, task) => {
// as our download progresses indicate the status
progress.onProgress = progessify(task, 'Downloading Cypress');
return download.start({
version,
downloadDestination,
progress
}).then(redirectVersion => {
if (redirectVersion) version = redirectVersion;
debug(`finished downloading file: ${downloadDestination}`);
}).then(() => {
// save the download destination for unzipping
util.setTaskTitle(task, util.titleize(chalk.green('Downloaded Cypress')), rendererOptions.renderer);
});
}
}, unzipTask({
progress,
zipFilePath: downloadDestination,
installDir,
rendererOptions
}), {
options: {
title: util.titleize('Finishing Installation')
},
task: (ctx, task) => {
const cleanup = () => {
debug('removing zip file %s', downloadDestination);
return fs.removeAsync(downloadDestination);
};
return cleanup().then(() => {
debug('finished installation in', installDir);
util.setTaskTitle(task, util.titleize(chalk.green('Finished Installation'), chalk.gray(installDir)), rendererOptions.renderer);
});
}
}], {
rendererOptions
});
// start the tasks!
return Promise.resolve(tasks.run());
};
const validateOS = () => {
return util.getPlatformInfo().then(platformInfo => {
return platformInfo.match(/(win32-x64|linux-x64|linux-arm64|darwin-x64|darwin-arm64)/);
});
};
/**
* Returns the version to install - either a string like `1.2.3` to be fetched
* from the download server or a file path or HTTP URL.
*/
function getVersionOverride({
arch,
envVarVersion,
buildInfo
}) {
// let this environment variable reset the binary version we need
if (envVarVersion) {
return envVarVersion;
}
if (buildInfo && !buildInfo.stable) {
logger.log(chalk.yellow(stripIndent`
${logSymbols.warning} Warning: You are installing a pre-release build of Cypress.
Bugs may be present which do not exist in production builds.
This build was created from:
* Commit SHA: ${buildInfo.commitSha}
* Commit Branch: ${buildInfo.commitBranch}
* Commit Timestamp: ${buildInfo.commitDate}
`));
logger.log();
return _getBinaryUrlFromBuildInfo(arch, buildInfo);
}
}
function getEnvVarVersion() {
if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return;
// because passed file paths are often double quoted
// and might have extra whitespace around, be robust and trim the string
const trimAndRemoveDoubleQuotes = true;
const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
return envVarVersion;
}
const start = async (options = {}) => {
debug('installing with options %j', options);
const envVarVersion = getEnvVarVersion();
if (envVarVersion === '0') {
debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
logger.log(stripIndent`
${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`);
logger.log();
return;
}
_.defaults(options, {
force: false,
buildInfo
});
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
const envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
logger.log(stripIndent`
${chalk.yellow('Note:')} Overriding Cypress cache directory to: ${chalk.cyan(envCache)}
Previous installs of Cypress may not be found.
`);
logger.log();
}
const pkgVersion = util.pkgVersion();
const arch = await util.getRealArch();
const versionOverride = getVersionOverride({
arch,
envVarVersion,
buildInfo: options.buildInfo
});
const versionToInstall = versionOverride || pkgVersion;
debug('version in package.json is %s, version to install is %s', pkgVersion, versionToInstall);
const installDir = state.getVersionDir(pkgVersion, options.buildInfo);
const cacheDir = state.getCacheDir();
const binaryDir = state.getBinaryDir(pkgVersion);
if (!(await validateOS())) {
return throwFormErrorText(errors.invalidOS)();
}
await fs.ensureDirAsync(cacheDir).catch({
code: 'EACCES'
}, err => {
return throwFormErrorText(errors.invalidCacheDirectory)(stripIndent`
Failed to access ${chalk.cyan(cacheDir)}:
${err.message}
`);
});
const binaryPkg = await state.getBinaryPkgAsync(binaryDir);
const binaryVersion = await state.getBinaryPkgVersion(binaryPkg);
const shouldInstall = () => {
if (!binaryVersion) {
debug('no binary installed under cli version');
return true;
}
logger.log();
logger.log(stripIndent`
Cypress ${chalk.green(binaryVersion)} is installed in ${chalk.cyan(installDir)}
`);
logger.log();
if (options.force) {
debug('performing force install over existing binary');
return true;
}
if (binaryVersion === versionToInstall || !util.isSemver(versionToInstall)) {
// our version matches, tell the user this is a noop
alreadyInstalledMsg();
return false;
}
return true;
};
// noop if we've been told not to download
if (!shouldInstall()) {
return debug('Not downloading or installing binary');
}
if (envVarVersion) {
logger.log(chalk.yellow(stripIndent`
${logSymbols.warning} Warning: Forcing a binary version different than the default.
The CLI expected to install version: ${chalk.green(pkgVersion)}
Instead we will install version: ${chalk.green(versionToInstall)}
These versions may not work properly together.
`));
logger.log();
}
const getLocalFilePath = async () => {
// see if version supplied is a path to a binary
if (await fs.pathExistsAsync(versionToInstall)) {
return path.extname(versionToInstall) === '.zip' ? versionToInstall : false;
}
const possibleFile = util.formAbsolutePath(versionToInstall);
debug('checking local file', possibleFile, 'cwd', process.cwd());
// if this exists return the path to it
// else false
if ((await fs.pathExistsAsync(possibleFile)) && path.extname(possibleFile) === '.zip') {
return possibleFile;
}
return false;
};
const pathToLocalFile = await getLocalFilePath();
if (pathToLocalFile) {
const absolutePath = path.resolve(versionToInstall);
debug('found local file at', absolutePath);
debug('skipping download');
const rendererOptions = getRendererOptions();
return new Listr([unzipTask({
progress: {
throttle: 100,
onProgress: null
},
zipFilePath: absolutePath,
installDir,
rendererOptions
})], {
rendererOptions
}).run();
}
if (options.force) {
debug('Cypress already installed at', installDir);
debug('but the installation was forced');
}
debug('preparing to download and unzip version ', versionToInstall, 'to path', installDir);
const downloadDir = os.tmpdir();
await downloadAndUnzip({
version: versionToInstall,
installDir,
downloadDir
});
// delay 1 sec for UX, unless we are testing
await Promise.delay(1000);
displayCompletionMsg();
};
module.exports = {
start,
_getBinaryUrlFromBuildInfo
};
const unzipTask = ({
zipFilePath,
installDir,
progress,
rendererOptions
}) => {
return {
options: {
title: util.titleize('Unzipping Cypress')
},
task: (ctx, task) => {
// as our unzip progresses indicate the status
progress.onProgress = progessify(task, 'Unzipping Cypress');
return unzip.start({
zipFilePath,
installDir,
progress
}).then(() => {
util.setTaskTitle(task, util.titleize(chalk.green('Unzipped Cypress')), rendererOptions.renderer);
});
}
};
};
const progessify = (task, title) => {
// return higher order function
return (percentComplete, remaining) => {
percentComplete = chalk.white(` ${percentComplete}%`);
// pluralize seconds remaining
remaining = chalk.gray(`${remaining}s`);
util.setTaskTitle(task, util.titleize(title, percentComplete, remaining), getRendererOptions().renderer);
};
};
// if we are running in CI then use
// the verbose renderer else use
// the default
const getRendererOptions = () => {
let renderer = util.isCi() ? verbose : 'default';
if (logger.logLevel() === 'silent') {
renderer = 'silent';
}
return {
renderer
};
};

185
CyLukTs/lukan/node_modules/cypress/lib/tasks/state.js generated vendored Normal file
View File

@ -0,0 +1,185 @@
"use strict";
const _ = require('lodash');
const os = require('os');
const path = require('path');
const untildify = require('untildify');
const debug = require('debug')('cypress:cli');
const fs = require('../fs');
const util = require('../util');
const getPlatformExecutable = () => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return 'Contents/MacOS/Cypress';
case 'linux':
return 'Cypress';
case 'win32':
return 'Cypress.exe';
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
const getPlatFormBinaryFolder = () => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return 'Cypress.app';
case 'linux':
return 'Cypress';
case 'win32':
return 'Cypress';
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
const getBinaryPkgPath = binaryDir => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return path.join(binaryDir, 'Contents', 'Resources', 'app', 'package.json');
case 'linux':
return path.join(binaryDir, 'resources', 'app', 'package.json');
case 'win32':
return path.join(binaryDir, 'resources', 'app', 'package.json');
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
/**
* Get path to binary directory
*/
const getBinaryDir = (version = util.pkgVersion()) => {
return path.join(getVersionDir(version), getPlatFormBinaryFolder());
};
const getVersionDir = (version = util.pkgVersion(), buildInfo = util.pkgBuildInfo()) => {
if (buildInfo && !buildInfo.stable) {
version = ['beta', version, buildInfo.commitBranch, buildInfo.commitSha.slice(0, 8)].join('-');
}
return path.join(getCacheDir(), version);
};
/**
* When executing "npm postinstall" hook, the working directory is set to
* "<current folder>/node_modules/cypress", which can be surprising when using relative paths.
*/
const isInstallingFromPostinstallHook = () => {
// individual folders
const cwdFolders = process.cwd().split(path.sep);
const length = cwdFolders.length;
return cwdFolders[length - 2] === 'node_modules' && cwdFolders[length - 1] === 'cypress';
};
const getCacheDir = () => {
let cache_directory = util.getCacheDir();
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
const envVarCacheDir = untildify(util.getEnv('CYPRESS_CACHE_FOLDER'));
debug('using environment variable CYPRESS_CACHE_FOLDER %s', envVarCacheDir);
if (!path.isAbsolute(envVarCacheDir) && isInstallingFromPostinstallHook()) {
const packageRootFolder = path.join('..', '..', envVarCacheDir);
cache_directory = path.resolve(packageRootFolder);
debug('installing from postinstall hook, original root folder is %s', packageRootFolder);
debug('and resolved cache directory is %s', cache_directory);
} else {
cache_directory = path.resolve(envVarCacheDir);
}
}
return cache_directory;
};
const parseRealPlatformBinaryFolderAsync = binaryPath => {
return fs.realpathAsync(binaryPath).then(realPath => {
debug('CYPRESS_RUN_BINARY has realpath:', realPath);
if (!realPath.toString().endsWith(getPlatformExecutable())) {
return false;
}
if (os.platform() === 'darwin') {
return path.resolve(realPath, '..', '..', '..');
}
return path.resolve(realPath, '..');
});
};
const getDistDir = () => {
return path.join(__dirname, '..', '..', 'dist');
};
/**
* Returns full filename to the file that keeps the Test Runner verification state as JSON text.
* Note: the binary state file will be stored one level up from the given binary folder.
* @param {string} binaryDir - full path to the folder holding the binary.
*/
const getBinaryStatePath = binaryDir => {
return path.join(binaryDir, '..', 'binary_state.json');
};
const getBinaryStateContentsAsync = binaryDir => {
const fullPath = getBinaryStatePath(binaryDir);
return fs.readJsonAsync(fullPath).catch({
code: 'ENOENT'
}, SyntaxError, () => {
debug('could not read binary_state.json file at "%s"', fullPath);
return {};
});
};
const getBinaryVerifiedAsync = binaryDir => {
return getBinaryStateContentsAsync(binaryDir).tap(debug).get('verified');
};
const clearBinaryStateAsync = binaryDir => {
return fs.removeAsync(getBinaryStatePath(binaryDir));
};
/**
* Writes the new binary status.
* @param {boolean} verified The new test runner state after smoke test
* @param {string} binaryDir Folder holding the binary
* @returns {Promise<void>} returns a promise
*/
const writeBinaryVerifiedAsync = (verified, binaryDir) => {
return getBinaryStateContentsAsync(binaryDir).then(contents => {
return fs.outputJsonAsync(getBinaryStatePath(binaryDir), _.extend(contents, {
verified
}), {
spaces: 2
});
});
};
const getPathToExecutable = binaryDir => {
return path.join(binaryDir, getPlatformExecutable());
};
/**
* Resolves with an object read from the binary app package.json file.
* If the file does not exist resolves with null
*/
const getBinaryPkgAsync = binaryDir => {
const pathToPackageJson = getBinaryPkgPath(binaryDir);
debug('Reading binary package.json from:', pathToPackageJson);
return fs.pathExistsAsync(pathToPackageJson).then(exists => {
if (!exists) {
return null;
}
return fs.readJsonAsync(pathToPackageJson);
});
};
const getBinaryPkgVersion = o => _.get(o, 'version', null);
const getBinaryElectronVersion = o => _.get(o, 'electronVersion', null);
const getBinaryElectronNodeVersion = o => _.get(o, 'electronNodeVersion', null);
module.exports = {
getPathToExecutable,
getPlatformExecutable,
// those names start to sound like Java
getBinaryElectronNodeVersion,
getBinaryElectronVersion,
getBinaryPkgVersion,
getBinaryVerifiedAsync,
getBinaryPkgAsync,
getBinaryPkgPath,
getBinaryDir,
getCacheDir,
clearBinaryStateAsync,
writeBinaryVerifiedAsync,
parseRealPlatformBinaryFolderAsync,
getDistDir,
getVersionDir
};

201
CyLukTs/lukan/node_modules/cypress/lib/tasks/unzip.js generated vendored Normal file
View File

@ -0,0 +1,201 @@
"use strict";
const _ = require('lodash');
const la = require('lazy-ass');
const is = require('check-more-types');
const cp = require('child_process');
const os = require('os');
const yauzl = require('yauzl');
const debug = require('debug')('cypress:cli:unzip');
const extract = require('extract-zip');
const Promise = require('bluebird');
const readline = require('readline');
const {
throwFormErrorText,
errors
} = require('../errors');
const fs = require('../fs');
const util = require('../util');
const unzipTools = {
extract
};
// expose this function for simple testing
const unzip = ({
zipFilePath,
installDir,
progress
}) => {
debug('unzipping from %s', zipFilePath);
debug('into', installDir);
if (!zipFilePath) {
throw new Error('Missing zip filename');
}
const startTime = Date.now();
let yauzlDoneTime = 0;
return fs.ensureDirAsync(installDir).then(() => {
return new Promise((resolve, reject) => {
return yauzl.open(zipFilePath, (err, zipFile) => {
yauzlDoneTime = Date.now();
if (err) {
debug('error using yauzl %s', err.message);
return reject(err);
}
const total = zipFile.entryCount;
debug('zipFile entries count', total);
const started = new Date();
let percent = 0;
let count = 0;
const notify = percent => {
const elapsed = +new Date() - +started;
const eta = util.calculateEta(percent, elapsed);
progress.onProgress(percent, util.secsRemaining(eta));
};
const tick = () => {
count += 1;
percent = count / total * 100;
const displayPercent = percent.toFixed(0);
return notify(displayPercent);
};
const unzipWithNode = () => {
debug('unzipping with node.js (slow)');
const opts = {
dir: installDir,
onEntry: tick
};
debug('calling Node extract tool %s %o', zipFilePath, opts);
return unzipTools.extract(zipFilePath, opts).then(() => {
debug('node unzip finished');
return resolve();
}).catch(err => {
if (err) {
debug('error %s', err.message);
return reject(err);
}
});
};
const unzipFallback = _.once(unzipWithNode);
const unzipWithUnzipTool = () => {
debug('unzipping via `unzip`');
const inflatingRe = /inflating:/;
const sp = cp.spawn('unzip', ['-o', zipFilePath, '-d', installDir]);
sp.on('error', err => {
debug('unzip tool error: %s', err.message);
unzipFallback();
});
sp.on('close', code => {
debug('unzip tool close with code %d', code);
if (code === 0) {
percent = 100;
notify(percent);
return resolve();
}
debug('`unzip` failed %o', {
code
});
return unzipFallback();
});
sp.stdout.on('data', data => {
if (inflatingRe.test(data)) {
return tick();
}
});
sp.stderr.on('data', data => {
debug('`unzip` stderr %s', data);
});
};
// we attempt to first unzip with the native osx
// ditto because its less likely to have problems
// with corruption, symlinks, or icons causing failures
// and can handle resource forks
// http://automatica.com.au/2011/02/unzip-mac-os-x-zip-in-terminal/
const unzipWithOsx = () => {
debug('unzipping via `ditto`');
const copyingFileRe = /^copying file/;
const sp = cp.spawn('ditto', ['-xkV', zipFilePath, installDir]);
// f-it just unzip with node
sp.on('error', err => {
debug(err.message);
unzipFallback();
});
sp.on('close', code => {
if (code === 0) {
// make sure we get to 100% on the progress bar
// because reading in lines is not really accurate
percent = 100;
notify(percent);
return resolve();
}
debug('`ditto` failed %o', {
code
});
return unzipFallback();
});
return readline.createInterface({
input: sp.stderr
}).on('line', line => {
if (copyingFileRe.test(line)) {
return tick();
}
});
};
switch (os.platform()) {
case 'darwin':
return unzipWithOsx();
case 'linux':
return unzipWithUnzipTool();
case 'win32':
return unzipWithNode();
default:
return;
}
});
}).tap(() => {
debug('unzip completed %o', {
yauzlMs: yauzlDoneTime - startTime,
unzipMs: Date.now() - yauzlDoneTime
});
});
});
};
function isMaybeWindowsMaxPathLengthError(err) {
return os.platform() === 'win32' && err.code === 'ENOENT' && err.syscall === 'realpath';
}
const start = async ({
zipFilePath,
installDir,
progress
}) => {
la(is.unemptyString(installDir), 'missing installDir');
if (!progress) {
progress = {
onProgress: () => {
return {};
}
};
}
try {
const installDirExists = await fs.pathExists(installDir);
if (installDirExists) {
debug('removing existing unzipped binary', installDir);
await fs.removeAsync(installDir);
}
await unzip({
zipFilePath,
installDir,
progress
});
} catch (err) {
const errorTemplate = isMaybeWindowsMaxPathLengthError(err) ? errors.failedUnzipWindowsMaxPathLength : errors.failedUnzip;
await throwFormErrorText(errorTemplate)(err);
}
};
module.exports = {
start,
utils: {
unzip,
unzipTools
}
};

295
CyLukTs/lukan/node_modules/cypress/lib/tasks/verify.js generated vendored Normal file
View File

@ -0,0 +1,295 @@
"use strict";
const _ = require('lodash');
const chalk = require('chalk');
const {
Listr
} = require('listr2');
const debug = require('debug')('cypress:cli');
const {
stripIndent
} = require('common-tags');
const Promise = require('bluebird');
const logSymbols = require('log-symbols');
const path = require('path');
const os = require('os');
const verbose = require('../VerboseRenderer');
const {
throwFormErrorText,
errors
} = require('../errors');
const util = require('../util');
const logger = require('../logger');
const xvfb = require('../exec/xvfb');
const state = require('./state');
const VERIFY_TEST_RUNNER_TIMEOUT_MS = +util.getEnv('CYPRESS_VERIFY_TIMEOUT') || 30000;
const checkExecutable = binaryDir => {
const executable = state.getPathToExecutable(binaryDir);
debug('checking if executable exists', executable);
return util.isExecutableAsync(executable).then(isExecutable => {
debug('Binary is executable? :', isExecutable);
if (!isExecutable) {
return throwFormErrorText(errors.binaryNotExecutable(executable))();
}
}).catch({
code: 'ENOENT'
}, () => {
if (util.isCi()) {
return throwFormErrorText(errors.notInstalledCI(executable))();
}
return throwFormErrorText(errors.missingApp(binaryDir))(stripIndent`
Cypress executable not found at: ${chalk.cyan(executable)}
`);
});
};
const runSmokeTest = (binaryDir, options) => {
let executable = state.getPathToExecutable(binaryDir);
const onSmokeTestError = (smokeTestCommand, linuxWithDisplayEnv) => {
return err => {
debug('Smoke test failed:', err);
let errMessage = err.stderr || err.message;
debug('error message:', errMessage);
if (err.timedOut) {
debug('error timedOut is true');
return throwFormErrorText(errors.smokeTestFailure(smokeTestCommand, true))(errMessage);
}
if (linuxWithDisplayEnv && util.isBrokenGtkDisplay(errMessage)) {
util.logBrokenGtkDisplayWarning();
return throwFormErrorText(errors.invalidSmokeTestDisplayError)(errMessage);
}
return throwFormErrorText(errors.missingDependency)(errMessage);
};
};
const needsXvfb = xvfb.isNeeded();
debug('needs Xvfb?', needsXvfb);
/**
* Spawn Cypress running smoke test to check if all operating system
* dependencies are good.
*/
const spawn = linuxWithDisplayEnv => {
const random = _.random(0, 1000);
const args = ['--smoke-test', `--ping=${random}`];
if (needsSandbox()) {
// electron requires --no-sandbox to run as root
debug('disabling Electron sandbox');
args.unshift('--no-sandbox');
}
if (options.dev) {
executable = 'node';
args.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
}
const smokeTestCommand = `${executable} ${args.join(' ')}`;
debug('running smoke test');
debug('using Cypress executable %s', executable);
debug('smoke test command:', smokeTestCommand);
debug('smoke test timeout %d ms', options.smokeTestTimeout);
const env = _.extend({}, process.env, {
ELECTRON_ENABLE_LOGGING: true
});
const stdioOptions = _.extend({}, {
env,
timeout: options.smokeTestTimeout
});
return Promise.resolve(util.exec(executable, args, stdioOptions)).catch(onSmokeTestError(smokeTestCommand, linuxWithDisplayEnv)).then(result => {
// TODO: when execa > 1.1 is released
// change this to `result.all` for both stderr and stdout
// use lodash to be robust during tests against null result or missing stdout
const smokeTestStdout = _.get(result, 'stdout', '');
debug('smoke test stdout "%s"', smokeTestStdout);
if (!util.stdoutLineMatches(String(random), smokeTestStdout)) {
debug('Smoke test failed because could not find %d in:', random, result);
const smokeTestStderr = _.get(result, 'stderr', '');
const errorText = smokeTestStderr || smokeTestStdout;
return throwFormErrorText(errors.smokeTestFailure(smokeTestCommand, false))(errorText);
}
});
};
const spawnInXvfb = linuxWithDisplayEnv => {
return xvfb.start().then(() => {
return spawn(linuxWithDisplayEnv);
}).finally(xvfb.stop);
};
const userFriendlySpawn = linuxWithDisplayEnv => {
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
return spawn(linuxWithDisplayEnv).catch({
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR'
}, () => {
return spawnInXvfb(linuxWithDisplayEnv);
});
};
if (needsXvfb) {
return spawnInXvfb();
}
// if we are on linux and there's already a DISPLAY
// set, then we may need to rerun cypress after
// spawning our own Xvfb server
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
return userFriendlySpawn(linuxWithDisplayEnv);
};
function testBinary(version, binaryDir, options) {
debug('running binary verification check', version);
// if running from 'cypress verify', don't print this message
if (!options.force) {
logger.log(stripIndent`
It looks like this is your first time using Cypress: ${chalk.cyan(version)}
`);
}
logger.log();
// if we are running in CI then use
// the verbose renderer else use
// the default
let renderer = util.isCi() ? verbose : 'default';
if (logger.logLevel() === 'silent') renderer = 'silent';
const rendererOptions = {
renderer
};
const tasks = new Listr([{
options: {
title: util.titleize('Verifying Cypress can run', chalk.gray(binaryDir))
},
task: (ctx, task) => {
debug('clearing out the verified version');
return state.clearBinaryStateAsync(binaryDir).then(() => {
return Promise.all([runSmokeTest(binaryDir, options), Promise.resolve().delay(1500) // good user experience
]);
}).then(() => {
debug('write verified: true');
return state.writeBinaryVerifiedAsync(true, binaryDir);
}).then(() => {
util.setTaskTitle(task, util.titleize(chalk.green('Verified Cypress!'), chalk.gray(binaryDir)), rendererOptions.renderer);
});
}
}], {
rendererOptions
});
return tasks.run();
}
const maybeVerify = (installedVersion, binaryDir, options) => {
return state.getBinaryVerifiedAsync(binaryDir).then(isVerified => {
debug('is Verified ?', isVerified);
let shouldVerify = !isVerified;
// force verify if options.force
if (options.force) {
debug('force verify');
shouldVerify = true;
}
if (shouldVerify) {
return testBinary(installedVersion, binaryDir, options).then(() => {
if (options.welcomeMessage) {
logger.log();
logger.log('Opening Cypress...');
}
});
}
});
};
const start = (options = {}) => {
debug('verifying Cypress app');
const packageVersion = util.pkgVersion();
let binaryDir = state.getBinaryDir(packageVersion);
_.defaults(options, {
dev: false,
force: false,
welcomeMessage: true,
smokeTestTimeout: VERIFY_TEST_RUNNER_TIMEOUT_MS
});
if (options.dev) {
return runSmokeTest('', options);
}
const parseBinaryEnvVar = () => {
const envBinaryPath = util.getEnv('CYPRESS_RUN_BINARY');
debug('CYPRESS_RUN_BINARY exists, =', envBinaryPath);
logger.log(stripIndent`
${chalk.yellow('Note:')} You have set the environment variable:
${chalk.white('CYPRESS_RUN_BINARY=')}${chalk.cyan(envBinaryPath)}
This overrides the default Cypress binary path used.
`);
logger.log();
return util.isExecutableAsync(envBinaryPath).then(isExecutable => {
debug('CYPRESS_RUN_BINARY is executable? :', isExecutable);
if (!isExecutable) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(stripIndent`
The supplied binary path is not executable
`);
}
}).then(() => {
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath);
}).then(envBinaryDir => {
if (!envBinaryDir) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
}
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
binaryDir = envBinaryDir;
}).catch({
code: 'ENOENT'
}, err => {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
});
};
return Promise.try(() => {
debug('checking environment variables');
if (util.getEnv('CYPRESS_RUN_BINARY')) {
return parseBinaryEnvVar();
}
}).then(() => {
return checkExecutable(binaryDir);
}).tap(() => {
return debug('binaryDir is ', binaryDir);
}).then(() => {
return state.getBinaryPkgAsync(binaryDir);
}).then(pkg => {
return state.getBinaryPkgVersion(pkg);
}).then(binaryVersion => {
if (!binaryVersion) {
debug('no Cypress binary found for cli version ', packageVersion);
return throwFormErrorText(errors.missingApp(binaryDir))(`
Cannot read binary version from: ${chalk.cyan(state.getBinaryPkgPath(binaryDir))}
`);
}
debug(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
if (binaryVersion !== packageVersion) {
// warn if we installed with CYPRESS_INSTALL_BINARY or changed version
// in the package.json
logger.log(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
logger.log();
logger.warn(stripIndent`
${logSymbols.warning} Warning: Binary version ${chalk.green(binaryVersion)} does not match the expected package version ${chalk.green(packageVersion)}
These versions may not work properly together.
`);
logger.log();
}
return maybeVerify(binaryVersion, binaryDir, options);
}).catch(err => {
if (err.known) {
throw err;
}
return throwFormErrorText(errors.unexpected)(err.stack);
});
};
const isLinuxLike = () => os.platform() !== 'win32';
/**
* Returns true if running on a system where Electron needs "--no-sandbox" flag.
* @see https://crbug.com/638180
*
* On Debian we had problems running in sandbox even for non-root users.
* @see https://github.com/cypress-io/cypress/issues/5434
* Seems there is a lot of discussion around this issue among Electron users
* @see https://github.com/electron/electron/issues/17972
*/
const needsSandbox = () => isLinuxLike();
module.exports = {
start,
VERIFY_TEST_RUNNER_TIMEOUT_MS,
needsSandbox
};

478
CyLukTs/lukan/node_modules/cypress/lib/util.js generated vendored Normal file
View File

@ -0,0 +1,478 @@
"use strict";
const _ = require('lodash');
const arch = require('arch');
const os = require('os');
const ospath = require('ospath');
const crypto = require('crypto');
const la = require('lazy-ass');
const is = require('check-more-types');
const tty = require('tty');
const path = require('path');
const isCi = require('is-ci');
const execa = require('execa');
const getos = require('getos');
const chalk = require('chalk');
const Promise = require('bluebird');
const cachedir = require('cachedir');
const logSymbols = require('log-symbols');
const executable = require('executable');
const {
stripIndent
} = require('common-tags');
const supportsColor = require('supports-color');
const isInstalledGlobally = require('is-installed-globally');
const logger = require('./logger');
const debug = require('debug')('cypress:cli');
const fs = require('./fs');
const semver = require('semver');
const pkg = require(path.join(__dirname, '..', 'package.json'));
const issuesUrl = 'https://github.com/cypress-io/cypress/issues';
const getosAsync = Promise.promisify(getos);
/**
* Returns SHA512 of a file
*
* Implementation lifted from https://github.com/sindresorhus/hasha
* but without bringing that dependency (since hasha is Node v8+)
*/
const getFileChecksum = filename => {
la(is.unemptyString(filename), 'expected filename', filename);
const hashStream = () => {
const s = crypto.createHash('sha512');
s.setEncoding('hex');
return s;
};
return new Promise((resolve, reject) => {
const stream = fs.createReadStream(filename);
stream.on('error', reject).pipe(hashStream()).on('error', reject).on('finish', function () {
resolve(this.read());
});
});
};
const getFileSize = filename => {
la(is.unemptyString(filename), 'expected filename', filename);
return fs.statAsync(filename).get('size');
};
const isBrokenGtkDisplayRe = /Gtk: cannot open display/;
const stringify = val => {
return _.isObject(val) ? JSON.stringify(val) : val;
};
function normalizeModuleOptions(options = {}) {
return _.mapValues(options, stringify);
}
/**
* Returns true if the platform is Linux. We do a lot of different
* stuff on Linux (like Xvfb) and it helps to has readable code
*/
const isLinux = () => {
return os.platform() === 'linux';
};
/**
* If the DISPLAY variable is set incorrectly, when trying to spawn
* Cypress executable we get an error like this:
```
[1005:0509/184205.663837:WARNING:browser_main_loop.cc(258)] Gtk: cannot open display: 99
```
*/
const isBrokenGtkDisplay = str => {
return isBrokenGtkDisplayRe.test(str);
};
const isPossibleLinuxWithIncorrectDisplay = () => {
return isLinux() && process.env.DISPLAY;
};
const logBrokenGtkDisplayWarning = () => {
debug('Cypress exited due to a broken gtk display because of a potential invalid DISPLAY env... retrying after starting Xvfb');
// if we get this error, we are on Linux and DISPLAY is set
logger.warn(stripIndent`
${logSymbols.warning} Warning: Cypress failed to start.
This is likely due to a misconfigured DISPLAY environment variable.
DISPLAY was set to: "${process.env.DISPLAY}"
Cypress will attempt to fix the problem and rerun.
`);
logger.warn();
};
function stdoutLineMatches(expectedLine, stdout) {
const lines = stdout.split('\n').map(val => val.trim());
return lines.some(line => line === expectedLine);
}
/**
* Confirms if given value is a valid CYPRESS_INTERNAL_ENV value. Undefined values
* are valid, because the system can set the default one.
*
* @param {string} value
* @example util.isValidCypressInternalEnvValue(process.env.CYPRESS_INTERNAL_ENV)
*/
function isValidCypressInternalEnvValue(value) {
if (_.isUndefined(value)) {
// will get default value
return true;
}
// names of config environments, see "packages/server/config/app.json"
const names = ['development', 'test', 'staging', 'production'];
return _.includes(names, value);
}
/**
* Confirms if given value is a non-production CYPRESS_INTERNAL_ENV value.
* Undefined values are valid, because the system can set the default one.
*
* @param {string} value
* @example util.isNonProductionCypressInternalEnvValue(process.env.CYPRESS_INTERNAL_ENV)
*/
function isNonProductionCypressInternalEnvValue(value) {
return !_.isUndefined(value) && value !== 'production';
}
/**
* Prints NODE_OPTIONS using debug() module, but only
* if DEBUG=cypress... is set
*/
function printNodeOptions(log = debug) {
if (!log.enabled) {
return;
}
if (process.env.NODE_OPTIONS) {
log('NODE_OPTIONS=%s', process.env.NODE_OPTIONS);
} else {
log('NODE_OPTIONS is not set');
}
}
/**
* Removes double quote characters
* from the start and end of the given string IF they are both present
*
* @param {string} str Input string
* @returns {string} Trimmed string or the original string if there are no double quotes around it.
* @example
```
dequote('"foo"')
// returns string 'foo'
dequote('foo')
// returns string 'foo'
```
*/
const dequote = str => {
la(is.string(str), 'expected a string to remove double quotes', str);
if (str.length > 1 && str[0] === '"' && str[str.length - 1] === '"') {
return str.substr(1, str.length - 2);
}
return str;
};
const parseOpts = opts => {
opts = _.pick(opts, 'autoCancelAfterFailures', 'browser', 'cachePath', 'cacheList', 'cacheClear', 'cachePrune', 'ciBuildId', 'ct', 'component', 'config', 'configFile', 'cypressVersion', 'destination', 'detached', 'dev', 'e2e', 'exit', 'env', 'force', 'global', 'group', 'headed', 'headless', 'inspect', 'inspectBrk', 'key', 'path', 'parallel', 'port', 'project', 'quiet', 'reporter', 'reporterOptions', 'record', 'runProject', 'spec', 'tag');
if (opts.exit) {
opts = _.omit(opts, 'exit');
}
// some options might be quoted - which leads to unexpected results
// remove double quotes from certain options
const cleanOpts = {
...opts
};
const toDequote = ['group', 'ciBuildId'];
for (const prop of toDequote) {
if (_.has(opts, prop)) {
cleanOpts[prop] = dequote(opts[prop]);
}
}
debug('parsed cli options %o', cleanOpts);
return cleanOpts;
};
/**
* Copy of packages/server/lib/browsers/utils.ts
* because we need same functionality in CLI to show the path :(
*/
const getApplicationDataFolder = (...paths) => {
const {
env
} = process;
// allow overriding the app_data folder
let folder = env.CYPRESS_CONFIG_ENV || env.CYPRESS_INTERNAL_ENV || 'development';
const PRODUCT_NAME = pkg.productName || pkg.name;
const OS_DATA_PATH = ospath.data();
const ELECTRON_APP_DATA_PATH = path.join(OS_DATA_PATH, PRODUCT_NAME);
if (process.env.CYPRESS_INTERNAL_E2E_TESTING_SELF) {
folder = `${folder}-e2e-test`;
}
const p = path.join(ELECTRON_APP_DATA_PATH, 'cy', folder, ...paths);
return p;
};
const util = {
normalizeModuleOptions,
parseOpts,
isValidCypressInternalEnvValue,
isNonProductionCypressInternalEnvValue,
printNodeOptions,
isCi() {
return isCi;
},
getEnvOverrides(options = {}) {
return _.chain({}).extend(util.getEnvColors()).extend(util.getForceTty()).omitBy(_.isUndefined) // remove undefined values
.mapValues(value => {
// stringify to 1 or 0
return value ? '1' : '0';
}).extend(util.getOriginalNodeOptions()).value();
},
getOriginalNodeOptions() {
const opts = {};
if (process.env.NODE_OPTIONS) {
opts.ORIGINAL_NODE_OPTIONS = process.env.NODE_OPTIONS;
}
// https://github.com/cypress-io/cypress/issues/18914
// Node 17+ ships with OpenSSL 3 by default, so we may need the option
// --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash
// function. This option doesn't exist on Node <17 or when it is built
// against OpenSSL 1, so we have to detect Node's major version and check
// which version of OpenSSL it was built against before spawning the plugins
// process.
// To be removed when the Cypress binary pulls in the @cypress/webpack-batteries-included-preprocessor
// version that has been updated to webpack >= 5.61, which no longer relies on
// Node's builtin crypto.hash function.
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && semver.satisfies(process.versions.openssl, '>=3', {
includePrerelease: true
})) {
opts.ORIGINAL_NODE_OPTIONS = `${opts.ORIGINAL_NODE_OPTIONS || ''} --openssl-legacy-provider`;
}
return opts;
},
getForceTty() {
return {
FORCE_STDIN_TTY: util.isTty(process.stdin.fd),
FORCE_STDOUT_TTY: util.isTty(process.stdout.fd),
FORCE_STDERR_TTY: util.isTty(process.stderr.fd)
};
},
getEnvColors() {
const sc = util.supportsColor();
return {
FORCE_COLOR: sc,
DEBUG_COLORS: sc,
MOCHA_COLORS: sc ? true : undefined
};
},
isTty(fd) {
return tty.isatty(fd);
},
supportsColor() {
// if we've been explictly told not to support
// color then turn this off
if (process.env.NO_COLOR) {
return false;
}
// https://github.com/cypress-io/cypress/issues/1747
// always return true in CI providers
if (process.env.CI) {
return true;
}
// ensure that both stdout and stderr support color
return Boolean(supportsColor.stdout) && Boolean(supportsColor.stderr);
},
cwd() {
return process.cwd();
},
pkgBuildInfo() {
return pkg.buildInfo;
},
pkgVersion() {
return pkg.version;
},
exit(code) {
process.exit(code);
},
logErrorExit1(err) {
logger.error(err.message);
process.exit(1);
},
dequote,
titleize(...args) {
// prepend first arg with space
// and pad so that all messages line up
args[0] = _.padEnd(` ${args[0]}`, 24);
// get rid of any falsy values
args = _.compact(args);
return chalk.blue(...args);
},
calculateEta(percent, elapsed) {
// returns the number of seconds remaining
// if we're at 100% already just return 0
if (percent === 100) {
return 0;
}
// take the percentage and divide by one
// and multiple that against elapsed
// subtracting what's already elapsed
return elapsed * (1 / (percent / 100)) - elapsed;
},
convertPercentToPercentage(num) {
// convert a percent with values between 0 and 1
// with decimals, so that it is between 0 and 100
// and has no decimal places
return Math.round(_.isFinite(num) ? num * 100 : 0);
},
secsRemaining(eta) {
// calculate the seconds reminaing with no decimal places
return (_.isFinite(eta) ? eta / 1000 : 0).toFixed(0);
},
setTaskTitle(task, title, renderer) {
// only update the renderer title when not running in CI
if (renderer === 'default' && task.title !== title) {
task.title = title;
}
},
isInstalledGlobally() {
return isInstalledGlobally;
},
isSemver(str) {
return /^(\d+\.)?(\d+\.)?(\*|\d+)$/.test(str);
},
isExecutableAsync(filePath) {
return Promise.resolve(executable(filePath));
},
isLinux,
getOsVersionAsync() {
return Promise.try(() => {
if (isLinux()) {
return getosAsync().then(osInfo => {
return [osInfo.dist, osInfo.release].join(' - ');
}).catch(() => {
return os.release();
});
}
return os.release();
});
},
async getPlatformInfo() {
const [version, osArch] = await Promise.all([util.getOsVersionAsync(), this.getRealArch()]);
return stripIndent`
Platform: ${os.platform()}-${osArch} (${version})
Cypress Version: ${util.pkgVersion()}
`;
},
_cachedArch: undefined,
/**
* Attempt to return the real system arch (not process.arch, which is only the Node binary's arch)
*/
async getRealArch() {
if (this._cachedArch) return this._cachedArch;
async function _getRealArch() {
const osPlatform = os.platform();
// eslint-disable-next-line no-restricted-syntax
const osArch = os.arch();
debug('detecting arch %o', {
osPlatform,
osArch
});
if (osArch === 'arm64') return 'arm64';
if (osPlatform === 'darwin') {
// could possibly be x64 node on arm64 darwin, check if we are being translated by Rosetta
// https://stackoverflow.com/a/65347893/3474615
const {
stdout
} = await execa('sysctl', ['-n', 'sysctl.proc_translated']).catch(() => '');
debug('rosetta check result: %o', {
stdout
});
if (stdout === '1') return 'arm64';
}
if (osPlatform === 'linux') {
// could possibly be x64 node on arm64 linux, check the "machine hardware name"
// list of names for reference: https://stackoverflow.com/a/45125525/3474615
const {
stdout
} = await execa('uname', ['-m']).catch(() => '');
debug('arm uname -m result: %o ', {
stdout
});
if (['aarch64_be', 'aarch64', 'armv8b', 'armv8l'].includes(stdout)) return 'arm64';
}
// eslint-disable-next-line no-restricted-syntax
const pkgArch = arch();
if (pkgArch === 'x86') return 'ia32';
return pkgArch;
}
return this._cachedArch = await _getRealArch();
},
// attention:
// when passing relative path to NPM post install hook, the current working
// directory is set to the `node_modules/cypress` folder
// the user is probably passing relative path with respect to root package folder
formAbsolutePath(filename) {
if (path.isAbsolute(filename)) {
return filename;
}
return path.join(process.cwd(), '..', '..', filename);
},
getEnv(varName, trim) {
la(is.unemptyString(varName), 'expected environment variable name, not', varName);
const configVarName = `npm_config_${varName}`;
const configVarNameLower = configVarName.toLowerCase();
const packageConfigVarName = `npm_package_config_${varName}`;
let result;
if (process.env.hasOwnProperty(varName)) {
debug(`Using ${varName} from environment variable`);
result = process.env[varName];
} else if (process.env.hasOwnProperty(configVarName)) {
debug(`Using ${varName} from npm config`);
result = process.env[configVarName];
} else if (process.env.hasOwnProperty(configVarNameLower)) {
debug(`Using ${varName.toLowerCase()} from npm config`);
result = process.env[configVarNameLower];
} else if (process.env.hasOwnProperty(packageConfigVarName)) {
debug(`Using ${varName} from package.json config`);
result = process.env[packageConfigVarName];
}
// environment variables are often set double quotes to escape characters
// and on Windows it can lead to weird things: for example
// set FOO="C:\foo.txt" && node -e "console.log('>>>%s<<<', process.env.FOO)"
// will print
// >>>"C:\foo.txt" <<<
// see https://github.com/cypress-io/cypress/issues/4506#issuecomment-506029942
// so for sanity sake we should first trim whitespace characters and remove
// double quotes around environment strings if the caller is expected to
// use this environment string as a file path
return trim ? dequote(_.trim(result)) : result;
},
getCacheDir() {
return cachedir('Cypress');
},
isPostInstall() {
return process.env.npm_lifecycle_event === 'postinstall';
},
exec: execa,
stdoutLineMatches,
issuesUrl,
isBrokenGtkDisplay,
logBrokenGtkDisplayWarning,
isPossibleLinuxWithIncorrectDisplay,
getGitHubIssueUrl(number) {
la(is.positive(number), 'github issue should be a positive number', number);
la(_.isInteger(number), 'github issue should be an integer', number);
return `${issuesUrl}/${number}`;
},
getFileChecksum,
getFileSize,
getApplicationDataFolder
};
module.exports = util;

View File

@ -0,0 +1,140 @@
# @cypress/mount-utils
> **Note** this package is not meant to be used outside of cypress component testing.
This library exports some shared types and utility functions designed to build adapters for components frameworks.
It is used in:
- [`@cypress/react`](https://github.com/cypress-io/cypress/tree/develop/npm/react)
- [`@cypress/vue`](https://github.com/cypress-io/cypress/tree/develop/npm/vue)
- [`@cypress/svelte`](https://github.com/cypress-io/cypress/tree/develop/npm/svelte)
- [`@cypress/angular`](https://github.com/cypress-io/cypress/tree/develop/npm/angular)
## What is a Mount Adapter?
All Component Tests require a component to be **mounted**. This is generally done with a custom command, `cy.mount` by default.
### Requirements
All the functionality used to create the first party Mount adapters is available to support third parties adapters. At minimum, a Mount Adapter must:
- Receive a component as the first argument. This could be class, function etc - depends on the framework.
- Return a Cypress Chainable (for example using `cy.wrap`) that resolves whatever is idiomatic for your framework
- Call `getContainerEl` to access the root DOM element
In addition, we recommend that Mount Adapters:
- call `setupHooks` to register the required lifecycle hooks for `@cypress/mount-utils` to work
### Example Mount Adapter: Web Components
Here's a simple yet realistic example of Mount Adapter targeting Web Components. It uses utilities from this package (`@cypress/mount-utils`) This is recommended, so your adapter behaves similar to the first party Mount Adapters.
```ts
import {
ROOT_SELECTOR,
setupHooks,
getContainerEl
} from "@cypress/mount-utils";
Cypress.on("run:start", () => {
// Consider doing a check to ensure your adapter only runs in Component Testing mode.
if (Cypress.testingType !== "component") {
return;
}
Cypress.on("test:before:run", () => {
// Do some cleanup from previous test - for example, clear the DOM.
getContainerEl().innerHTML = "";
});
});
function maybeRegisterComponent<T extends CustomElementConstructor>(
name: string,
webComponent: T
) {
// Avoid double-registering a Web Component.
if (window.customElements.get(name)) {
return;
}
window.customElements.define(name, webComponent);
}
export function mount(
webComponent: CustomElementConstructor
): Cypress.Chainable {
// Get root selector defined in `cypress/support.component-index.html
const $root = document.querySelector(ROOT_SELECTOR)!;
// Change to kebab-case to comply with Web Component naming convention
const name = webComponent.name
.replace(/([a-z09])([A-Z])/g, "$1-$2")
.toLowerCase();
/// Register Web Component
maybeRegisterComponent(name, webComponent);
// Render HTML containing component.
$root.innerHTML = `<${name} id="root"></${name}>`;
// Log a messsage in the Command Log.
Cypress.log({
name: "mount",
message: [`<${name} ... />`],
});
// Return a `Cypress.Chainable` that returns whatever is idiomatic
// in the framework your mount adapter targets.
return cy.wrap(document.querySelector("#root"), { log: false });
}
// Setup Cypress lifecycle hooks.
setupHooks();
```
Usage:
```ts
// User will generally register a `cy.mount` command in `cypress/support/component.js`:
import { mount } from '@package/cypress-web-components'
Cypress.Commands.add('mount', mount)
// Test
export class WebCounter extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = `
<div>
<button>Counter</button>
</div>`;
}
}
describe('web-component.cy.ts', () => {
it('playground', () => {
cy.mount(WebCounter)
})
})
```
For more robust, production ready examples, check out our first party adapters.
## Compatibility
| @cypress/mount-utils | cypress |
| -------------------- | ------- |
| <= v1 | <= v9 |
| >= v2 | >= v10 |
## Changelog
[Changelog](./CHANGELOG.md)

View File

@ -0,0 +1,40 @@
export declare const ROOT_SELECTOR = "[data-cy-root]";
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
export declare const getContainerEl: () => HTMLElement;
export declare function checkForRemovedStyleOptions(mountingOptions: Record<string, any>): void;
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
export declare function setupHooks(optionalCallback?: Function): void;
/**
* Remove any style or extra link elements from the iframe placeholder
* left from any previous test
*
* Removed as of Cypress 11.0.0
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
export declare function cleanupStyles(): void;
/**
* Additional styles to inject into the document.
* A component might need 3rd party libraries from CDN,
* local CSS files and custom styles.
*
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
export declare type StyleOptions = unknown;
/**
* Injects custom style text or CSS file or 3rd party style resources
* into the given document.
*
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
export declare const injectStylesBeforeElement: (options: Partial<StyleOptions & {
log: boolean;
}>, document: Document, el: HTMLElement | null) => void;

View File

@ -0,0 +1,68 @@
export const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
export const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
export function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
export function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
/**
* Remove any style or extra link elements from the iframe placeholder
* left from any previous test
*
* Removed as of Cypress 11.0.0
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
export function cleanupStyles() {
Cypress.utils.throwErrByPath('mount.cleanup_styles');
}
/**
* Injects custom style text or CSS file or 3rd party style resources
* into the given document.
*
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
export const injectStylesBeforeElement = (options, document, el) => {
Cypress.utils.throwErrByPath('mount.inject_styles_before_element');
};

View File

@ -0,0 +1,37 @@
{
"name": "@cypress/mount-utils",
"version": "0.0.0-development",
"description": "Shared utilities for the various component testing adapters",
"main": "dist/index.js",
"scripts": {
"build": "tsc || echo 'built, with type errors'",
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
"build-prod": "yarn build",
"check-ts": "tsc --noEmit",
"watch": "tsc -w",
"lint": "eslint --ext .js,.ts,.json, ."
},
"dependencies": {},
"devDependencies": {
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-node-resolve": "^11.1.1",
"rollup": "3.7.3",
"rollup-plugin-dts": "5.0.0",
"rollup-plugin-typescript2": "^0.29.0",
"typescript": "^4.7.4"
},
"files": [
"dist"
],
"types": "dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"homepage": "https://github.com/cypress-io/cypress/tree/develop/npm/mount-utils#readme",
"bugs": "https://github.com/cypress-io/cypress/issues/new?template=1-bug-report.md",
"publishConfig": {
"access": "public"
}
}

151
CyLukTs/lukan/node_modules/cypress/package.json generated vendored Normal file
View File

@ -0,0 +1,151 @@
{
"name": "cypress",
"version": "12.13.0",
"main": "index.js",
"scripts": {
"postinstall": "node index.js --exec install",
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";"
},
"dependencies": {
"@cypress/request": "^2.88.10",
"@cypress/xvfb": "^1.2.4",
"@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
"buffer": "^5.6.0",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1",
"commander": "^6.2.1",
"common-tags": "^1.8.0",
"dayjs": "^1.10.4",
"debug": "^4.3.4",
"enquirer": "^2.3.6",
"eventemitter2": "6.4.7",
"execa": "4.1.0",
"executable": "^4.1.1",
"extract-zip": "2.0.1",
"figures": "^3.2.0",
"fs-extra": "^9.1.0",
"getos": "^3.2.1",
"is-ci": "^3.0.0",
"is-installed-globally": "~0.4.0",
"lazy-ass": "^1.6.0",
"listr2": "^3.8.3",
"lodash": "^4.17.21",
"log-symbols": "^4.0.0",
"minimist": "^1.2.8",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
"proxy-from-env": "1.0.0",
"request-progress": "^3.0.0",
"semver": "^7.3.2",
"supports-color": "^8.1.1",
"tmp": "~0.2.1",
"untildify": "^4.0.0",
"yauzl": "^2.10.0"
},
"files": [
"bin",
"lib",
"index.js",
"index.mjs",
"types/**/*.d.ts",
"mount-utils",
"vue",
"react",
"vue2",
"react18",
"angular",
"svelte"
],
"bin": {
"cypress": "bin/cypress"
},
"engines": {
"node": "^14.0.0 || ^16.0.0 || >=18.0.0"
},
"types": "types",
"exports": {
".": {
"types": "./types/index.d.ts",
"import": "./index.mjs",
"require": "./index.js"
},
"./vue": {
"types": "./vue/dist/index.d.ts",
"import": "./vue/dist/cypress-vue.esm-bundler.js",
"require": "./vue/dist/cypress-vue.cjs.js"
},
"./vue2": {
"types": "./vue2/dist/index.d.ts",
"import": "./vue2/dist/cypress-vue2.esm-bundler.js",
"require": "./vue2/dist/cypress-vue2.cjs.js"
},
"./package.json": {
"import": "./package.json",
"require": "./package.json"
},
"./react": {
"types": "./react/dist/index.d.ts",
"import": "./react/dist/cypress-react.esm-bundler.js",
"require": "./react/dist/cypress-react.cjs.js"
},
"./react18": {
"types": "./react18/dist/index.d.ts",
"import": "./react18/dist/cypress-react.esm-bundler.js",
"require": "./react18/dist/cypress-react.cjs.js"
},
"./mount-utils": {
"types": "./mount-utils/dist/index.d.ts",
"require": "./mount-utils/dist/index.js"
},
"./angular": {
"types": "./angular/dist/index.d.ts",
"import": "./angular/dist/index.js",
"require": "./angular/dist/index.js"
},
"./svelte": {
"types": "./svelte/dist/index.d.ts",
"import": "./svelte/dist/cypress-svelte.esm-bundler.js",
"require": "./svelte/dist/cypress-svelte.cjs.js"
}
},
"buildInfo": {
"commitBranch": "develop",
"commitSha": "b71788d87df83eeb844c7e9de2ee106d2724fa9c",
"commitDate": "2023-05-23T19:18:49.000Z",
"stable": true
},
"description": "Cypress is a next generation front end testing tool built for the modern web",
"homepage": "https://github.com/cypress-io/cypress",
"license": "MIT",
"bugs": {
"url": "https://github.com/cypress-io/cypress/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"keywords": [
"automation",
"browser",
"cypress",
"cypress.io",
"e2e",
"end-to-end",
"integration",
"component",
"mocks",
"runner",
"spies",
"stubs",
"test",
"testing"
]
}

14
CyLukTs/lukan/node_modules/cypress/react/README.md generated vendored Normal file
View File

@ -0,0 +1,14 @@
# @cypress/react
Mount React components in the open source [Cypress.io](https://www.cypress.io/) test runner
> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [React Component Testing Docs](https://docs.cypress.io/guides/component-testing/react/overview) for mounting React components. Installing and importing `mount` from `@cypress/react` should only be done for advanced use-cases.
## Development
Run `yarn build` to compile and sync packages to the `cypress` cli package.
Run `yarn cy:open` to open Cypress component testing against real-world examples.
Run `yarn test` to execute headless Cypress tests.
## [Changelog](./CHANGELOG.md)

View File

@ -0,0 +1,876 @@
/**
* @cypress/react v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/**
* Gets the display name of the component when possible.
* @param type {JSX} The type object returned from creating the react element.
* @param fallbackName {string} The alias, or fallback name to use when the name cannot be derived.
* @link https://github.com/facebook/react-devtools/blob/master/backend/getDisplayName.js
*/
function getDisplayName(node, fallbackName = 'Unknown') {
const type = node === null || node === void 0 ? void 0 : node.type;
if (!type) {
return fallbackName;
}
let displayName = null;
// The displayName property is not guaranteed to be a string.
// It's only safe to use for our purposes if it's a string.
// github.com/facebook/react-devtools/issues/803
if (typeof type.displayName === 'string') {
displayName = type.displayName;
}
if (!displayName) {
displayName = type.name || fallbackName;
}
// Facebook-specific hack to turn "Image [from Image.react]" into just "Image".
// We need displayName with module name for error reports but it clutters the DevTools.
const match = displayName.match(/^(.*) \[from (.*)\]$/);
if (match) {
const componentName = match[1];
const moduleName = match[2];
if (componentName && moduleName) {
if (moduleName === componentName ||
moduleName.startsWith(`${componentName}.`)) {
displayName = componentName;
}
}
}
return displayName;
}
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
let mountCleanup;
/**
* Create an `mount` function. Performs all the non-React-version specific
* behavior related to mounting. The React-version-specific code
* is injected. This helps us to maintain a consistent public API
* and handle breaking changes in React's rendering API.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*/
const makeMountFn = (type, jsx, options = {}, rerenderKey, internalMountOptions) => {
if (!internalMountOptions) {
throw Error('internalMountOptions must be provided with `render` and `reactDom` parameters');
}
// @ts-expect-error - this is removed but we want to check if a user is passing it, and error if they are.
if (options.alias) {
// @ts-expect-error
Cypress.utils.throwErrByPath('mount.alias', options.alias);
}
checkForRemovedStyleOptions(options);
mountCleanup = internalMountOptions.cleanup;
return cy
.then(() => {
var _a, _b, _c;
const reactDomToUse = internalMountOptions.reactDom;
const el = getContainerEl();
if (!el) {
throw new Error([
`[@cypress/react] 🔥 Hmm, cannot find root element to mount the component. Searched for ${ROOT_SELECTOR}`,
].join(' '));
}
const key = rerenderKey !== null && rerenderKey !== void 0 ? rerenderKey :
// @ts-ignore provide unique key to the the wrapped component to make sure we are rerendering between tests
(((_c = (_b = (_a = Cypress === null || Cypress === void 0 ? void 0 : Cypress.mocha) === null || _a === void 0 ? void 0 : _a.getRunner()) === null || _b === void 0 ? void 0 : _b.test) === null || _c === void 0 ? void 0 : _c.title) || '') + Math.random();
const props = {
key,
};
const reactComponent = React__namespace.createElement(options.strict ? React__namespace.StrictMode : React__namespace.Fragment, props, jsx);
// since we always surround the component with a fragment
// let's get back the original component
const userComponent = reactComponent.props.children;
internalMountOptions.render(reactComponent, el, reactDomToUse);
return (cy.wrap(userComponent, { log: false })
.then(() => {
return cy.wrap({
component: userComponent,
rerender: (newComponent) => makeMountFn('rerender', newComponent, options, key, internalMountOptions),
unmount: () => {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
},
}, { log: false });
})
// by waiting, we delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
// https://github.com/bahmutov/cypress-react-unit-test/issues/200
.wait(0, { log: false })
.then(() => {
if (options.log !== false) {
// Get the display name property via the component constructor
// @ts-ignore FIXME
const componentName = getDisplayName(jsx);
const jsxComponentName = `<${componentName} ... />`;
Cypress.log({
name: type,
type: 'parent',
message: [jsxComponentName],
// @ts-ignore
$el: el.children.item(0),
consoleProps: () => {
return {
// @ts-ignore protect the use of jsx functional components use ReactNode
props: jsx === null || jsx === void 0 ? void 0 : jsx.props,
description: type === 'mount' ? 'Mounts React component' : 'Rerenders mounted React component',
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
}));
// Bluebird types are terrible. I don't think the return type can be carried without this cast
});
};
/**
* Create an `unmount` function. Performs all the non-React-version specific
* behavior related to unmounting.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
const makeUnmountFn = (options) => {
return cy.then(() => {
var _a;
const wasUnmounted = mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
if (wasUnmounted && options.log) {
Cypress.log({
name: 'unmount',
type: 'parent',
message: [(_a = options.boundComponentMessage) !== null && _a !== void 0 ? _a : 'Unmounted component'],
consoleProps: () => {
return {
description: 'Unmounts React component',
parent: getContainerEl().parentNode,
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
});
};
// Cleanup before each run
// NOTE: we cannot use unmount here because
// we are not in the context of a test
const preMountCleanup = () => {
mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
};
const _mount = (jsx, options = {}) => makeMountFn('mount', jsx, options);
const createMount = (defaultOptions) => {
return (element, options) => {
return _mount(element, Object.assign(Object.assign({}, defaultOptions), options));
};
};
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
// it is required to unmount component in beforeEach hook in order to provide a clean state inside test
// because `mount` can be called after some preparation that can side effect unmount
// @see npm/react/cypress/component/advanced/set-timeout-example/loading-indicator-spec.js
setupHooks(preMountCleanup);
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {};
var debug_1 = debug;
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0';
const MAX_LENGTH$1 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991;
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16;
var constants = {
SEMVER_SPEC_VERSION,
MAX_LENGTH: MAX_LENGTH$1,
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
MAX_SAFE_COMPONENT_LENGTH,
};
function createCommonjsModule(fn) {
var module = { exports: {} };
return fn(module, module.exports), module.exports;
}
var re_1 = createCommonjsModule(function (module, exports) {
const { MAX_SAFE_COMPONENT_LENGTH } = constants;
exports = module.exports = {};
// The actual regexps go on exports.re
const re = exports.re = [];
const src = exports.src = [];
const t = exports.t = {};
let R = 0;
const createToken = (name, value, isGlobal) => {
const index = R++;
debug_1(name, index, value);
t[name] = index;
src[index] = value;
re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
};
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`);
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`);
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`);
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`);
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`);
createToken('FULL', `^${src[t.FULLPLAIN]}$`);
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`);
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
createToken('GTLT', '((?:<|>)?=?)');
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`);
createToken('COERCERTL', src[t.COERCE], true);
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)');
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = '$1~';
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)');
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = '$1^';
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = '$1$2$3';
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`);
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`);
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*');
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
});
// parse out just the options we care about so we always get a consistent
// obj with keys in a consistent order.
const opts = ['includePrerelease', 'loose', 'rtl'];
const parseOptions = options =>
!options ? {}
: typeof options !== 'object' ? { loose: true }
: opts.filter(k => options[k]).reduce((o, k) => {
o[k] = true;
return o
}, {});
var parseOptions_1 = parseOptions;
const numeric = /^[0-9]+$/;
const compareIdentifiers$1 = (a, b) => {
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
a = +a;
b = +b;
}
return a === b ? 0
: (anum && !bnum) ? -1
: (bnum && !anum) ? 1
: a < b ? -1
: 1
};
const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);
var identifiers = {
compareIdentifiers: compareIdentifiers$1,
rcompareIdentifiers,
};
const { MAX_LENGTH, MAX_SAFE_INTEGER } = constants;
const { re, t } = re_1;
const { compareIdentifiers } = identifiers;
class SemVer {
constructor (version, options) {
options = parseOptions_1(options);
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version;
}
} else if (typeof version !== 'string') {
throw new TypeError(`Invalid Version: ${version}`)
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
)
}
debug_1('SemVer', version, options);
this.options = options;
this.loose = !!options.loose;
// this isn't actually relevant for versions, but keep it so that we
// don't run into trouble passing this.options around.
this.includePrerelease = !!options.includePrerelease;
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
if (!m) {
throw new TypeError(`Invalid Version: ${version}`)
}
this.raw = version;
// these are actually numbers
this.major = +m[1];
this.minor = +m[2];
this.patch = +m[3];
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError('Invalid major version')
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError('Invalid minor version')
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError('Invalid patch version')
}
// numberify any prerelease numeric ids
if (!m[4]) {
this.prerelease = [];
} else {
this.prerelease = m[4].split('.').map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id;
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num
}
}
return id
});
}
this.build = m[5] ? m[5].split('.') : [];
this.format();
}
format () {
this.version = `${this.major}.${this.minor}.${this.patch}`;
if (this.prerelease.length) {
this.version += `-${this.prerelease.join('.')}`;
}
return this.version
}
toString () {
return this.version
}
compare (other) {
debug_1('SemVer.compare', this.version, this.options, other);
if (!(other instanceof SemVer)) {
if (typeof other === 'string' && other === this.version) {
return 0
}
other = new SemVer(other, this.options);
}
if (other.version === this.version) {
return 0
}
return this.compareMain(other) || this.comparePre(other)
}
compareMain (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
return (
compareIdentifiers(this.major, other.major) ||
compareIdentifiers(this.minor, other.minor) ||
compareIdentifiers(this.patch, other.patch)
)
}
comparePre (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
// NOT having a prerelease is > having one
if (this.prerelease.length && !other.prerelease.length) {
return -1
} else if (!this.prerelease.length && other.prerelease.length) {
return 1
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0
}
let i = 0;
do {
const a = this.prerelease[i];
const b = other.prerelease[i];
debug_1('prerelease compare', i, a, b);
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
compareBuild (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
let i = 0;
do {
const a = this.build[i];
const b = other.build[i];
debug_1('prerelease compare', i, a, b);
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier) {
switch (release) {
case 'premajor':
this.prerelease.length = 0;
this.patch = 0;
this.minor = 0;
this.major++;
this.inc('pre', identifier);
break
case 'preminor':
this.prerelease.length = 0;
this.patch = 0;
this.minor++;
this.inc('pre', identifier);
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0;
this.inc('patch', identifier);
this.inc('pre', identifier);
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier);
}
this.inc('pre', identifier);
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
// Otherwise increment major.
// 1.0.0-5 bumps to 1.0.0
// 1.1.0 bumps to 2.0.0
if (
this.minor !== 0 ||
this.patch !== 0 ||
this.prerelease.length === 0
) {
this.major++;
}
this.minor = 0;
this.patch = 0;
this.prerelease = [];
break
case 'minor':
// If this is a pre-minor version, bump up to the same minor version.
// Otherwise increment minor.
// 1.2.0-5 bumps to 1.2.0
// 1.2.1 bumps to 1.3.0
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++;
}
this.patch = 0;
this.prerelease = [];
break
case 'patch':
// If this is not a pre-release version, it will increment the patch.
// If it is a pre-release it will bump up to the same patch version.
// 1.2.0-5 patches to 1.2.0
// 1.2.0 patches to 1.2.1
if (this.prerelease.length === 0) {
this.patch++;
}
this.prerelease = [];
break
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case 'pre':
if (this.prerelease.length === 0) {
this.prerelease = [0];
} else {
let i = this.prerelease.length;
while (--i >= 0) {
if (typeof this.prerelease[i] === 'number') {
this.prerelease[i]++;
i = -2;
}
}
if (i === -1) {
// didn't increment anything
this.prerelease.push(0);
}
}
if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0];
}
} else {
this.prerelease = [identifier, 0];
}
}
break
default:
throw new Error(`invalid increment argument: ${release}`)
}
this.format();
this.raw = this.version;
return this
}
}
var semver = SemVer;
const major = (a, loose) => new semver(a, loose).major;
var major_1 = major;
let lastReactDom;
const cleanup = () => {
if (lastReactDom) {
const root = getContainerEl();
lastReactDom.unmountComponentAtNode(root);
return true;
}
return false;
};
/**
* Mounts a React component into the DOM.
* @param jsx {React.ReactNode} The React component to mount.
* @param options {MountOptions} [options={}] options to pass to the mount function.
* @param rerenderKey {string} [rerenderKey] A key to use to force a rerender.
* @see {@link https://on.cypress.io/mounting-react} for more details.
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*/
function mount(jsx, options = {}, rerenderKey) {
if (major_1(React.version) === 18) {
const message = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.';
console.error(message);
Cypress.log({ name: 'warning', message });
}
// Remove last mounted component if cy.mount is called more than once in a test
cleanup();
const internalOptions = {
reactDom: ReactDOM,
render: (reactComponent, el, reactDomToUse) => {
lastReactDom = (reactDomToUse || ReactDOM);
return lastReactDom.render(reactComponent, el);
},
unmount: internalUnmount,
cleanup,
};
return makeMountFn('mount', jsx, Object.assign({ ReactDom: ReactDOM }, options), rerenderKey, internalOptions);
}
/**
* Unmounts the component from the DOM.
* @internal
* @param options - Options for unmounting.
*/
function internalUnmount(options = { log: true }) {
return makeUnmountFn(options);
}
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
function unmount(options = { log: true }) {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
}
/**
* Mounts a React hook function in a test component for testing.
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
const mountHook = (hookFn) => {
// @ts-expect-error - internal API
Cypress.utils.throwErrByPath('mount.mount_hook');
};
exports.createMount = createMount;
exports.getContainerEl = getContainerEl;
exports.makeMountFn = makeMountFn;
exports.makeUnmountFn = makeUnmountFn;
exports.mount = mount;
exports.mountHook = mountHook;
exports.unmount = unmount;

View File

@ -0,0 +1,850 @@
/**
* @cypress/react v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
import * as React from 'react';
import React__default from 'react';
import ReactDOM from 'react-dom';
/**
* Gets the display name of the component when possible.
* @param type {JSX} The type object returned from creating the react element.
* @param fallbackName {string} The alias, or fallback name to use when the name cannot be derived.
* @link https://github.com/facebook/react-devtools/blob/master/backend/getDisplayName.js
*/
function getDisplayName(node, fallbackName = 'Unknown') {
const type = node === null || node === void 0 ? void 0 : node.type;
if (!type) {
return fallbackName;
}
let displayName = null;
// The displayName property is not guaranteed to be a string.
// It's only safe to use for our purposes if it's a string.
// github.com/facebook/react-devtools/issues/803
if (typeof type.displayName === 'string') {
displayName = type.displayName;
}
if (!displayName) {
displayName = type.name || fallbackName;
}
// Facebook-specific hack to turn "Image [from Image.react]" into just "Image".
// We need displayName with module name for error reports but it clutters the DevTools.
const match = displayName.match(/^(.*) \[from (.*)\]$/);
if (match) {
const componentName = match[1];
const moduleName = match[2];
if (componentName && moduleName) {
if (moduleName === componentName ||
moduleName.startsWith(`${componentName}.`)) {
displayName = componentName;
}
}
}
return displayName;
}
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
let mountCleanup;
/**
* Create an `mount` function. Performs all the non-React-version specific
* behavior related to mounting. The React-version-specific code
* is injected. This helps us to maintain a consistent public API
* and handle breaking changes in React's rendering API.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*/
const makeMountFn = (type, jsx, options = {}, rerenderKey, internalMountOptions) => {
if (!internalMountOptions) {
throw Error('internalMountOptions must be provided with `render` and `reactDom` parameters');
}
// @ts-expect-error - this is removed but we want to check if a user is passing it, and error if they are.
if (options.alias) {
// @ts-expect-error
Cypress.utils.throwErrByPath('mount.alias', options.alias);
}
checkForRemovedStyleOptions(options);
mountCleanup = internalMountOptions.cleanup;
return cy
.then(() => {
var _a, _b, _c;
const reactDomToUse = internalMountOptions.reactDom;
const el = getContainerEl();
if (!el) {
throw new Error([
`[@cypress/react] 🔥 Hmm, cannot find root element to mount the component. Searched for ${ROOT_SELECTOR}`,
].join(' '));
}
const key = rerenderKey !== null && rerenderKey !== void 0 ? rerenderKey :
// @ts-ignore provide unique key to the the wrapped component to make sure we are rerendering between tests
(((_c = (_b = (_a = Cypress === null || Cypress === void 0 ? void 0 : Cypress.mocha) === null || _a === void 0 ? void 0 : _a.getRunner()) === null || _b === void 0 ? void 0 : _b.test) === null || _c === void 0 ? void 0 : _c.title) || '') + Math.random();
const props = {
key,
};
const reactComponent = React.createElement(options.strict ? React.StrictMode : React.Fragment, props, jsx);
// since we always surround the component with a fragment
// let's get back the original component
const userComponent = reactComponent.props.children;
internalMountOptions.render(reactComponent, el, reactDomToUse);
return (cy.wrap(userComponent, { log: false })
.then(() => {
return cy.wrap({
component: userComponent,
rerender: (newComponent) => makeMountFn('rerender', newComponent, options, key, internalMountOptions),
unmount: () => {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
},
}, { log: false });
})
// by waiting, we delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
// https://github.com/bahmutov/cypress-react-unit-test/issues/200
.wait(0, { log: false })
.then(() => {
if (options.log !== false) {
// Get the display name property via the component constructor
// @ts-ignore FIXME
const componentName = getDisplayName(jsx);
const jsxComponentName = `<${componentName} ... />`;
Cypress.log({
name: type,
type: 'parent',
message: [jsxComponentName],
// @ts-ignore
$el: el.children.item(0),
consoleProps: () => {
return {
// @ts-ignore protect the use of jsx functional components use ReactNode
props: jsx === null || jsx === void 0 ? void 0 : jsx.props,
description: type === 'mount' ? 'Mounts React component' : 'Rerenders mounted React component',
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
}));
// Bluebird types are terrible. I don't think the return type can be carried without this cast
});
};
/**
* Create an `unmount` function. Performs all the non-React-version specific
* behavior related to unmounting.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
const makeUnmountFn = (options) => {
return cy.then(() => {
var _a;
const wasUnmounted = mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
if (wasUnmounted && options.log) {
Cypress.log({
name: 'unmount',
type: 'parent',
message: [(_a = options.boundComponentMessage) !== null && _a !== void 0 ? _a : 'Unmounted component'],
consoleProps: () => {
return {
description: 'Unmounts React component',
parent: getContainerEl().parentNode,
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
});
};
// Cleanup before each run
// NOTE: we cannot use unmount here because
// we are not in the context of a test
const preMountCleanup = () => {
mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
};
const _mount = (jsx, options = {}) => makeMountFn('mount', jsx, options);
const createMount = (defaultOptions) => {
return (element, options) => {
return _mount(element, Object.assign(Object.assign({}, defaultOptions), options));
};
};
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
// it is required to unmount component in beforeEach hook in order to provide a clean state inside test
// because `mount` can be called after some preparation that can side effect unmount
// @see npm/react/cypress/component/advanced/set-timeout-example/loading-indicator-spec.js
setupHooks(preMountCleanup);
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {};
var debug_1 = debug;
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0';
const MAX_LENGTH$1 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991;
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16;
var constants = {
SEMVER_SPEC_VERSION,
MAX_LENGTH: MAX_LENGTH$1,
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
MAX_SAFE_COMPONENT_LENGTH,
};
function createCommonjsModule(fn) {
var module = { exports: {} };
return fn(module, module.exports), module.exports;
}
var re_1 = createCommonjsModule(function (module, exports) {
const { MAX_SAFE_COMPONENT_LENGTH } = constants;
exports = module.exports = {};
// The actual regexps go on exports.re
const re = exports.re = [];
const src = exports.src = [];
const t = exports.t = {};
let R = 0;
const createToken = (name, value, isGlobal) => {
const index = R++;
debug_1(name, index, value);
t[name] = index;
src[index] = value;
re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
};
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`);
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`);
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`);
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`);
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`);
createToken('FULL', `^${src[t.FULLPLAIN]}$`);
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`);
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
createToken('GTLT', '((?:<|>)?=?)');
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`);
createToken('COERCERTL', src[t.COERCE], true);
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)');
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = '$1~';
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)');
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = '$1^';
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = '$1$2$3';
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`);
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`);
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*');
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
});
// parse out just the options we care about so we always get a consistent
// obj with keys in a consistent order.
const opts = ['includePrerelease', 'loose', 'rtl'];
const parseOptions = options =>
!options ? {}
: typeof options !== 'object' ? { loose: true }
: opts.filter(k => options[k]).reduce((o, k) => {
o[k] = true;
return o
}, {});
var parseOptions_1 = parseOptions;
const numeric = /^[0-9]+$/;
const compareIdentifiers$1 = (a, b) => {
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
a = +a;
b = +b;
}
return a === b ? 0
: (anum && !bnum) ? -1
: (bnum && !anum) ? 1
: a < b ? -1
: 1
};
const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);
var identifiers = {
compareIdentifiers: compareIdentifiers$1,
rcompareIdentifiers,
};
const { MAX_LENGTH, MAX_SAFE_INTEGER } = constants;
const { re, t } = re_1;
const { compareIdentifiers } = identifiers;
class SemVer {
constructor (version, options) {
options = parseOptions_1(options);
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version;
}
} else if (typeof version !== 'string') {
throw new TypeError(`Invalid Version: ${version}`)
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
)
}
debug_1('SemVer', version, options);
this.options = options;
this.loose = !!options.loose;
// this isn't actually relevant for versions, but keep it so that we
// don't run into trouble passing this.options around.
this.includePrerelease = !!options.includePrerelease;
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
if (!m) {
throw new TypeError(`Invalid Version: ${version}`)
}
this.raw = version;
// these are actually numbers
this.major = +m[1];
this.minor = +m[2];
this.patch = +m[3];
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError('Invalid major version')
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError('Invalid minor version')
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError('Invalid patch version')
}
// numberify any prerelease numeric ids
if (!m[4]) {
this.prerelease = [];
} else {
this.prerelease = m[4].split('.').map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id;
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num
}
}
return id
});
}
this.build = m[5] ? m[5].split('.') : [];
this.format();
}
format () {
this.version = `${this.major}.${this.minor}.${this.patch}`;
if (this.prerelease.length) {
this.version += `-${this.prerelease.join('.')}`;
}
return this.version
}
toString () {
return this.version
}
compare (other) {
debug_1('SemVer.compare', this.version, this.options, other);
if (!(other instanceof SemVer)) {
if (typeof other === 'string' && other === this.version) {
return 0
}
other = new SemVer(other, this.options);
}
if (other.version === this.version) {
return 0
}
return this.compareMain(other) || this.comparePre(other)
}
compareMain (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
return (
compareIdentifiers(this.major, other.major) ||
compareIdentifiers(this.minor, other.minor) ||
compareIdentifiers(this.patch, other.patch)
)
}
comparePre (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
// NOT having a prerelease is > having one
if (this.prerelease.length && !other.prerelease.length) {
return -1
} else if (!this.prerelease.length && other.prerelease.length) {
return 1
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0
}
let i = 0;
do {
const a = this.prerelease[i];
const b = other.prerelease[i];
debug_1('prerelease compare', i, a, b);
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
compareBuild (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options);
}
let i = 0;
do {
const a = this.build[i];
const b = other.build[i];
debug_1('prerelease compare', i, a, b);
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier) {
switch (release) {
case 'premajor':
this.prerelease.length = 0;
this.patch = 0;
this.minor = 0;
this.major++;
this.inc('pre', identifier);
break
case 'preminor':
this.prerelease.length = 0;
this.patch = 0;
this.minor++;
this.inc('pre', identifier);
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0;
this.inc('patch', identifier);
this.inc('pre', identifier);
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier);
}
this.inc('pre', identifier);
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
// Otherwise increment major.
// 1.0.0-5 bumps to 1.0.0
// 1.1.0 bumps to 2.0.0
if (
this.minor !== 0 ||
this.patch !== 0 ||
this.prerelease.length === 0
) {
this.major++;
}
this.minor = 0;
this.patch = 0;
this.prerelease = [];
break
case 'minor':
// If this is a pre-minor version, bump up to the same minor version.
// Otherwise increment minor.
// 1.2.0-5 bumps to 1.2.0
// 1.2.1 bumps to 1.3.0
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++;
}
this.patch = 0;
this.prerelease = [];
break
case 'patch':
// If this is not a pre-release version, it will increment the patch.
// If it is a pre-release it will bump up to the same patch version.
// 1.2.0-5 patches to 1.2.0
// 1.2.0 patches to 1.2.1
if (this.prerelease.length === 0) {
this.patch++;
}
this.prerelease = [];
break
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case 'pre':
if (this.prerelease.length === 0) {
this.prerelease = [0];
} else {
let i = this.prerelease.length;
while (--i >= 0) {
if (typeof this.prerelease[i] === 'number') {
this.prerelease[i]++;
i = -2;
}
}
if (i === -1) {
// didn't increment anything
this.prerelease.push(0);
}
}
if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0];
}
} else {
this.prerelease = [identifier, 0];
}
}
break
default:
throw new Error(`invalid increment argument: ${release}`)
}
this.format();
this.raw = this.version;
return this
}
}
var semver = SemVer;
const major = (a, loose) => new semver(a, loose).major;
var major_1 = major;
let lastReactDom;
const cleanup = () => {
if (lastReactDom) {
const root = getContainerEl();
lastReactDom.unmountComponentAtNode(root);
return true;
}
return false;
};
/**
* Mounts a React component into the DOM.
* @param jsx {React.ReactNode} The React component to mount.
* @param options {MountOptions} [options={}] options to pass to the mount function.
* @param rerenderKey {string} [rerenderKey] A key to use to force a rerender.
* @see {@link https://on.cypress.io/mounting-react} for more details.
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*/
function mount(jsx, options = {}, rerenderKey) {
if (major_1(React__default.version) === 18) {
const message = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.';
console.error(message);
Cypress.log({ name: 'warning', message });
}
// Remove last mounted component if cy.mount is called more than once in a test
cleanup();
const internalOptions = {
reactDom: ReactDOM,
render: (reactComponent, el, reactDomToUse) => {
lastReactDom = (reactDomToUse || ReactDOM);
return lastReactDom.render(reactComponent, el);
},
unmount: internalUnmount,
cleanup,
};
return makeMountFn('mount', jsx, Object.assign({ ReactDom: ReactDOM }, options), rerenderKey, internalOptions);
}
/**
* Unmounts the component from the DOM.
* @internal
* @param options - Options for unmounting.
*/
function internalUnmount(options = { log: true }) {
return makeUnmountFn(options);
}
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
function unmount(options = { log: true }) {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
}
/**
* Mounts a React hook function in a test component for testing.
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
const mountHook = (hookFn) => {
// @ts-expect-error - internal API
Cypress.utils.throwErrByPath('mount.mount_hook');
};
export { createMount, getContainerEl, makeMountFn, makeUnmountFn, mount, mountHook, unmount };

View File

@ -0,0 +1,111 @@
/// <reference types="cypress" />
import * as React from 'react';
import React__default from 'react';
import * as react_dom from 'react-dom';
interface UnmountArgs {
log: boolean;
boundComponentMessage?: string;
}
declare type MountOptions = Partial<MountReactComponentOptions>;
interface MountReactComponentOptions {
ReactDom: typeof react_dom;
/**
* Log the mounting command into Cypress Command Log,
* true by default.
*/
log: boolean;
/**
* Render component in React [strict mode](https://reactjs.org/docs/strict-mode.html)
* It activates additional checks and warnings for child components.
*/
strict: boolean;
}
interface InternalMountOptions {
reactDom: typeof react_dom;
render: (reactComponent: ReturnType<typeof React__default.createElement>, el: HTMLElement, reactDomToUse: typeof react_dom) => void;
unmount: (options: UnmountArgs) => void;
cleanup: () => boolean;
}
interface MountReturn {
/**
* The component that was rendered.
*/
component: React__default.ReactNode;
/**
* Rerenders the specified component with new props. This allows testing of components that store state (`setState`)
* or have asynchronous updates (`useEffect`, `useLayoutEffect`).
*/
rerender: (component: React__default.ReactNode) => globalThis.Cypress.Chainable<MountReturn>;
/**
* Removes the mounted component.
*
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
unmount: (payload: UnmountArgs) => void;
}
/**
* Create an `mount` function. Performs all the non-React-version specific
* behavior related to mounting. The React-version-specific code
* is injected. This helps us to maintain a consistent public API
* and handle breaking changes in React's rendering API.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*/
declare const makeMountFn: (type: 'mount' | 'rerender', jsx: React.ReactNode, options?: MountOptions, rerenderKey?: string, internalMountOptions?: InternalMountOptions) => globalThis.Cypress.Chainable<MountReturn>;
/**
* Create an `unmount` function. Performs all the non-React-version specific
* behavior related to unmounting.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
declare const makeUnmountFn: (options: UnmountArgs) => Cypress.Chainable<undefined>;
declare const createMount: (defaultOptions: MountOptions) => (element: React.ReactElement, options?: MountOptions) => Cypress.Chainable<MountReturn>;
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
declare const getContainerEl: () => HTMLElement;
/**
* Mounts a React component into the DOM.
* @param jsx {React.ReactNode} The React component to mount.
* @param options {MountOptions} [options={}] options to pass to the mount function.
* @param rerenderKey {string} [rerenderKey] A key to use to force a rerender.
* @see {@link https://on.cypress.io/mounting-react} for more details.
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*/
declare function mount(jsx: React__default.ReactNode, options?: MountOptions, rerenderKey?: string): Cypress.Chainable<MountReturn>;
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
declare function unmount(options?: {
log: boolean;
}): void;
/**
* Mounts a React hook function in a test component for testing.
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
declare const mountHook: <T>(hookFn: (...args: any[]) => T) => void;
export { InternalMountOptions, MountOptions, MountReactComponentOptions, MountReturn, UnmountArgs, createMount, getContainerEl, makeMountFn, makeUnmountFn, mount, mountHook, unmount };

98
CyLukTs/lukan/node_modules/cypress/react/package.json generated vendored Normal file
View File

@ -0,0 +1,98 @@
{
"name": "@cypress/react",
"version": "0.0.0-development",
"description": "Test React components using Cypress",
"main": "dist/cypress-react.cjs.js",
"scripts": {
"build": "rimraf dist && rollup -c rollup.config.mjs",
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
"build-prod": "yarn build",
"cy:open": "node ../../scripts/cypress.js open --component",
"cy:open:debug": "node --inspect-brk ../../scripts/start.js --component-testing --run-project ${PWD}",
"cy:run": "node ../../scripts/cypress.js run --component",
"cy:run:debug": "node --inspect-brk ../../scripts/start.js --component-testing --run-project ${PWD}",
"test": "yarn cy:run",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, .",
"watch": "yarn build --watch --watch.exclude ./dist/**/*"
},
"devDependencies": {
"@cypress/mount-utils": "0.0.0-development",
"@types/semver": "7.3.9",
"@vitejs/plugin-react": "4.0.0",
"axios": "0.21.2",
"cypress": "0.0.0-development",
"prop-types": "15.7.2",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-router": "6.0.0-alpha.1",
"react-router-dom": "6.0.0-alpha.1",
"semver": "^7.3.2",
"typescript": "^4.7.4",
"vite": "4.3.2",
"vite-plugin-require-transform": "1.0.12"
},
"peerDependencies": {
"@types/react": "^16.9.16 || ^17.0.0",
"cypress": "*",
"react": "^=16.x || ^=17.x",
"react-dom": "^=16.x || ^=17.x"
},
"files": [
"dist"
],
"types": "dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/react/#readme",
"author": "Gleb Bahmutov <gleb.bahmutov@gmail.com>",
"bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Freact&template=1-bug-report.md&title=",
"keywords": [
"react",
"cypress",
"cypress-io",
"test",
"testing"
],
"contributors": [
{
"name": "Dmitriy Kovalenko",
"social": "@dmtrKovalenko"
},
{
"name": "Brian Mann",
"social": "@brian-mann"
},
{
"name": "Barthélémy Ledoux",
"social": "@elevatebart"
},
{
"name": "Lachlan Miller",
"social": "@lmiller1990"
},
{
"name": "Jessica Sachs",
"social": "@_JessicaSachs"
}
],
"unpkg": "dist/cypress-react.browser.js",
"module": "dist/cypress-react.esm-bundler.js",
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"publishConfig": {
"access": "public"
},
"standard": {
"globals": [
"Cypress",
"cy",
"expect"
]
}
}

7
CyLukTs/lukan/node_modules/cypress/react18/README.md generated vendored Normal file
View File

@ -0,0 +1,7 @@
# @cypress/react18
Mount React 18 components in the open source [Cypress.io](https://www.cypress.io/) test runner
> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [React Component Testing Docs](https://docs.cypress.io/guides/component-testing/react/overview) for mounting React components. Installing and importing `mount` from `@cypress/react18` should only be done for advanced use-cases.
## [Changelog](./CHANGELOG.md)

View File

@ -0,0 +1,544 @@
/**
* @cypress/react18 v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
'use strict';
var ReactDOM = require('react-dom/client');
var React = require('react');
require('react-dom');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const ROOT_SELECTOR$1 = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl$1 = () => {
const el = document.querySelector(ROOT_SELECTOR$1);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR$1}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
/**
* Gets the display name of the component when possible.
* @param type {JSX} The type object returned from creating the react element.
* @param fallbackName {string} The alias, or fallback name to use when the name cannot be derived.
* @link https://github.com/facebook/react-devtools/blob/master/backend/getDisplayName.js
*/
function getDisplayName(node, fallbackName = 'Unknown') {
const type = node === null || node === void 0 ? void 0 : node.type;
if (!type) {
return fallbackName;
}
let displayName = null;
// The displayName property is not guaranteed to be a string.
// It's only safe to use for our purposes if it's a string.
// github.com/facebook/react-devtools/issues/803
if (typeof type.displayName === 'string') {
displayName = type.displayName;
}
if (!displayName) {
displayName = type.name || fallbackName;
}
// Facebook-specific hack to turn "Image [from Image.react]" into just "Image".
// We need displayName with module name for error reports but it clutters the DevTools.
const match = displayName.match(/^(.*) \[from (.*)\]$/);
if (match) {
const componentName = match[1];
const moduleName = match[2];
if (componentName && moduleName) {
if (moduleName === componentName ||
moduleName.startsWith(`${componentName}.`)) {
displayName = componentName;
}
}
}
return displayName;
}
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
let mountCleanup;
/**
* Create an `mount` function. Performs all the non-React-version specific
* behavior related to mounting. The React-version-specific code
* is injected. This helps us to maintain a consistent public API
* and handle breaking changes in React's rendering API.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*/
const makeMountFn = (type, jsx, options = {}, rerenderKey, internalMountOptions) => {
if (!internalMountOptions) {
throw Error('internalMountOptions must be provided with `render` and `reactDom` parameters');
}
// @ts-expect-error - this is removed but we want to check if a user is passing it, and error if they are.
if (options.alias) {
// @ts-expect-error
Cypress.utils.throwErrByPath('mount.alias', options.alias);
}
checkForRemovedStyleOptions(options);
mountCleanup = internalMountOptions.cleanup;
return cy
.then(() => {
var _a, _b, _c;
const reactDomToUse = internalMountOptions.reactDom;
const el = getContainerEl();
if (!el) {
throw new Error([
`[@cypress/react] 🔥 Hmm, cannot find root element to mount the component. Searched for ${ROOT_SELECTOR}`,
].join(' '));
}
const key = rerenderKey !== null && rerenderKey !== void 0 ? rerenderKey :
// @ts-ignore provide unique key to the the wrapped component to make sure we are rerendering between tests
(((_c = (_b = (_a = Cypress === null || Cypress === void 0 ? void 0 : Cypress.mocha) === null || _a === void 0 ? void 0 : _a.getRunner()) === null || _b === void 0 ? void 0 : _b.test) === null || _c === void 0 ? void 0 : _c.title) || '') + Math.random();
const props = {
key,
};
const reactComponent = React__namespace.createElement(options.strict ? React__namespace.StrictMode : React__namespace.Fragment, props, jsx);
// since we always surround the component with a fragment
// let's get back the original component
const userComponent = reactComponent.props.children;
internalMountOptions.render(reactComponent, el, reactDomToUse);
return (cy.wrap(userComponent, { log: false })
.then(() => {
return cy.wrap({
component: userComponent,
rerender: (newComponent) => makeMountFn('rerender', newComponent, options, key, internalMountOptions),
unmount: () => {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
},
}, { log: false });
})
// by waiting, we delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
// https://github.com/bahmutov/cypress-react-unit-test/issues/200
.wait(0, { log: false })
.then(() => {
if (options.log !== false) {
// Get the display name property via the component constructor
// @ts-ignore FIXME
const componentName = getDisplayName(jsx);
const jsxComponentName = `<${componentName} ... />`;
Cypress.log({
name: type,
type: 'parent',
message: [jsxComponentName],
// @ts-ignore
$el: el.children.item(0),
consoleProps: () => {
return {
// @ts-ignore protect the use of jsx functional components use ReactNode
props: jsx === null || jsx === void 0 ? void 0 : jsx.props,
description: type === 'mount' ? 'Mounts React component' : 'Rerenders mounted React component',
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
}));
// Bluebird types are terrible. I don't think the return type can be carried without this cast
});
};
/**
* Create an `unmount` function. Performs all the non-React-version specific
* behavior related to unmounting.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
const makeUnmountFn = (options) => {
return cy.then(() => {
var _a;
const wasUnmounted = mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
if (wasUnmounted && options.log) {
Cypress.log({
name: 'unmount',
type: 'parent',
message: [(_a = options.boundComponentMessage) !== null && _a !== void 0 ? _a : 'Unmounted component'],
consoleProps: () => {
return {
description: 'Unmounts React component',
parent: getContainerEl().parentNode,
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
});
};
// Cleanup before each run
// NOTE: we cannot use unmount here because
// we are not in the context of a test
const preMountCleanup = () => {
mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
};
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
// it is required to unmount component in beforeEach hook in order to provide a clean state inside test
// because `mount` can be called after some preparation that can side effect unmount
// @see npm/react/cypress/component/advanced/set-timeout-example/loading-indicator-spec.js
setupHooks(preMountCleanup);
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {};
var debug_1 = debug;
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0';
const MAX_LENGTH$1 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991;
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16;
var constants = {
SEMVER_SPEC_VERSION,
MAX_LENGTH: MAX_LENGTH$1,
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
MAX_SAFE_COMPONENT_LENGTH,
};
function createCommonjsModule(fn) {
var module = { exports: {} };
return fn(module, module.exports), module.exports;
}
createCommonjsModule(function (module, exports) {
const { MAX_SAFE_COMPONENT_LENGTH } = constants;
exports = module.exports = {};
// The actual regexps go on exports.re
const re = exports.re = [];
const src = exports.src = [];
const t = exports.t = {};
let R = 0;
const createToken = (name, value, isGlobal) => {
const index = R++;
debug_1(name, index, value);
t[name] = index;
src[index] = value;
re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
};
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`);
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`);
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`);
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`);
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`);
createToken('FULL', `^${src[t.FULLPLAIN]}$`);
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`);
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
createToken('GTLT', '((?:<|>)?=?)');
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`);
createToken('COERCERTL', src[t.COERCE], true);
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)');
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = '$1~';
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)');
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = '$1^';
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = '$1$2$3';
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`);
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`);
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*');
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
});
// @ts-expect-error
let root;
const cleanup = () => {
if (root) {
root.unmount();
root = null;
return true;
}
return false;
};
/**
* Mounts a React component into the DOM.
* @param {import('react').JSX.Element} jsx The React component to mount.
* @param {MountOptions} options Options to pass to the mount function.
* @param {string} rerenderKey A key to use to force a rerender.
*
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*
* @see {@link https://on.cypress.io/mounting-react} for more details.
*
* @returns {Cypress.Chainable<MountReturn>} The mounted component.
*/
function mount(jsx, options = {}, rerenderKey) {
// Remove last mounted component if cy.mount is called more than once in a test
// React by default removes the last component when calling render, but we should remove the root
// to wipe away any state
cleanup();
const internalOptions = {
reactDom: ReactDOM,
render: (reactComponent, el) => {
if (!root) {
root = ReactDOM.createRoot(el);
}
return root.render(reactComponent);
},
unmount: internalUnmount,
cleanup,
};
return makeMountFn('mount', jsx, Object.assign({ ReactDom: ReactDOM }, options), rerenderKey, internalOptions);
}
function internalUnmount(options = { log: true }) {
return makeUnmountFn(options);
}
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
function unmount(options = { log: true }) {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
}
exports.getContainerEl = getContainerEl$1;
exports.mount = mount;
exports.unmount = unmount;

View File

@ -0,0 +1,521 @@
/**
* @cypress/react18 v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
import ReactDOM from 'react-dom/client';
import * as React from 'react';
import 'react-dom';
const ROOT_SELECTOR$1 = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl$1 = () => {
const el = document.querySelector(ROOT_SELECTOR$1);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR$1}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
/**
* Gets the display name of the component when possible.
* @param type {JSX} The type object returned from creating the react element.
* @param fallbackName {string} The alias, or fallback name to use when the name cannot be derived.
* @link https://github.com/facebook/react-devtools/blob/master/backend/getDisplayName.js
*/
function getDisplayName(node, fallbackName = 'Unknown') {
const type = node === null || node === void 0 ? void 0 : node.type;
if (!type) {
return fallbackName;
}
let displayName = null;
// The displayName property is not guaranteed to be a string.
// It's only safe to use for our purposes if it's a string.
// github.com/facebook/react-devtools/issues/803
if (typeof type.displayName === 'string') {
displayName = type.displayName;
}
if (!displayName) {
displayName = type.name || fallbackName;
}
// Facebook-specific hack to turn "Image [from Image.react]" into just "Image".
// We need displayName with module name for error reports but it clutters the DevTools.
const match = displayName.match(/^(.*) \[from (.*)\]$/);
if (match) {
const componentName = match[1];
const moduleName = match[2];
if (componentName && moduleName) {
if (moduleName === componentName ||
moduleName.startsWith(`${componentName}.`)) {
displayName = componentName;
}
}
}
return displayName;
}
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
let mountCleanup;
/**
* Create an `mount` function. Performs all the non-React-version specific
* behavior related to mounting. The React-version-specific code
* is injected. This helps us to maintain a consistent public API
* and handle breaking changes in React's rendering API.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*/
const makeMountFn = (type, jsx, options = {}, rerenderKey, internalMountOptions) => {
if (!internalMountOptions) {
throw Error('internalMountOptions must be provided with `render` and `reactDom` parameters');
}
// @ts-expect-error - this is removed but we want to check if a user is passing it, and error if they are.
if (options.alias) {
// @ts-expect-error
Cypress.utils.throwErrByPath('mount.alias', options.alias);
}
checkForRemovedStyleOptions(options);
mountCleanup = internalMountOptions.cleanup;
return cy
.then(() => {
var _a, _b, _c;
const reactDomToUse = internalMountOptions.reactDom;
const el = getContainerEl();
if (!el) {
throw new Error([
`[@cypress/react] 🔥 Hmm, cannot find root element to mount the component. Searched for ${ROOT_SELECTOR}`,
].join(' '));
}
const key = rerenderKey !== null && rerenderKey !== void 0 ? rerenderKey :
// @ts-ignore provide unique key to the the wrapped component to make sure we are rerendering between tests
(((_c = (_b = (_a = Cypress === null || Cypress === void 0 ? void 0 : Cypress.mocha) === null || _a === void 0 ? void 0 : _a.getRunner()) === null || _b === void 0 ? void 0 : _b.test) === null || _c === void 0 ? void 0 : _c.title) || '') + Math.random();
const props = {
key,
};
const reactComponent = React.createElement(options.strict ? React.StrictMode : React.Fragment, props, jsx);
// since we always surround the component with a fragment
// let's get back the original component
const userComponent = reactComponent.props.children;
internalMountOptions.render(reactComponent, el, reactDomToUse);
return (cy.wrap(userComponent, { log: false })
.then(() => {
return cy.wrap({
component: userComponent,
rerender: (newComponent) => makeMountFn('rerender', newComponent, options, key, internalMountOptions),
unmount: () => {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
},
}, { log: false });
})
// by waiting, we delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
// https://github.com/bahmutov/cypress-react-unit-test/issues/200
.wait(0, { log: false })
.then(() => {
if (options.log !== false) {
// Get the display name property via the component constructor
// @ts-ignore FIXME
const componentName = getDisplayName(jsx);
const jsxComponentName = `<${componentName} ... />`;
Cypress.log({
name: type,
type: 'parent',
message: [jsxComponentName],
// @ts-ignore
$el: el.children.item(0),
consoleProps: () => {
return {
// @ts-ignore protect the use of jsx functional components use ReactNode
props: jsx === null || jsx === void 0 ? void 0 : jsx.props,
description: type === 'mount' ? 'Mounts React component' : 'Rerenders mounted React component',
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
}));
// Bluebird types are terrible. I don't think the return type can be carried without this cast
});
};
/**
* Create an `unmount` function. Performs all the non-React-version specific
* behavior related to unmounting.
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
const makeUnmountFn = (options) => {
return cy.then(() => {
var _a;
const wasUnmounted = mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
if (wasUnmounted && options.log) {
Cypress.log({
name: 'unmount',
type: 'parent',
message: [(_a = options.boundComponentMessage) !== null && _a !== void 0 ? _a : 'Unmounted component'],
consoleProps: () => {
return {
description: 'Unmounts React component',
parent: getContainerEl().parentNode,
home: 'https://github.com/cypress-io/cypress',
};
},
});
}
});
};
// Cleanup before each run
// NOTE: we cannot use unmount here because
// we are not in the context of a test
const preMountCleanup = () => {
mountCleanup === null || mountCleanup === void 0 ? void 0 : mountCleanup();
};
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
// it is required to unmount component in beforeEach hook in order to provide a clean state inside test
// because `mount` can be called after some preparation that can side effect unmount
// @see npm/react/cypress/component/advanced/set-timeout-example/loading-indicator-spec.js
setupHooks(preMountCleanup);
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {};
var debug_1 = debug;
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0';
const MAX_LENGTH$1 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991;
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16;
var constants = {
SEMVER_SPEC_VERSION,
MAX_LENGTH: MAX_LENGTH$1,
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
MAX_SAFE_COMPONENT_LENGTH,
};
function createCommonjsModule(fn) {
var module = { exports: {} };
return fn(module, module.exports), module.exports;
}
createCommonjsModule(function (module, exports) {
const { MAX_SAFE_COMPONENT_LENGTH } = constants;
exports = module.exports = {};
// The actual regexps go on exports.re
const re = exports.re = [];
const src = exports.src = [];
const t = exports.t = {};
let R = 0;
const createToken = (name, value, isGlobal) => {
const index = R++;
debug_1(name, index, value);
t[name] = index;
src[index] = value;
re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
};
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`);
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`);
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`);
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`);
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`);
createToken('FULL', `^${src[t.FULLPLAIN]}$`);
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`);
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
createToken('GTLT', '((?:<|>)?=?)');
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`);
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`);
createToken('COERCERTL', src[t.COERCE], true);
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)');
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = '$1~';
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)');
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = '$1^';
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = '$1$2$3';
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`);
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`);
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*');
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
});
// @ts-expect-error
let root;
const cleanup = () => {
if (root) {
root.unmount();
root = null;
return true;
}
return false;
};
/**
* Mounts a React component into the DOM.
* @param {import('react').JSX.Element} jsx The React component to mount.
* @param {MountOptions} options Options to pass to the mount function.
* @param {string} rerenderKey A key to use to force a rerender.
*
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*
* @see {@link https://on.cypress.io/mounting-react} for more details.
*
* @returns {Cypress.Chainable<MountReturn>} The mounted component.
*/
function mount(jsx, options = {}, rerenderKey) {
// Remove last mounted component if cy.mount is called more than once in a test
// React by default removes the last component when calling render, but we should remove the root
// to wipe away any state
cleanup();
const internalOptions = {
reactDom: ReactDOM,
render: (reactComponent, el) => {
if (!root) {
root = ReactDOM.createRoot(el);
}
return root.render(reactComponent);
},
unmount: internalUnmount,
cleanup,
};
return makeMountFn('mount', jsx, Object.assign({ ReactDom: ReactDOM }, options), rerenderKey, internalOptions);
}
function internalUnmount(options = { log: true }) {
return makeUnmountFn(options);
}
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
function unmount(options = { log: true }) {
// @ts-expect-error - undocumented API
Cypress.utils.throwErrByPath('mount.unmount');
}
export { getContainerEl$1 as getContainerEl, mount, unmount };

View File

@ -0,0 +1,78 @@
/// <reference types="cypress" />
/// <reference types="cypress" />
import React__default from 'react';
import * as react_dom from 'react-dom';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
declare const getContainerEl: () => HTMLElement;
interface UnmountArgs {
log: boolean;
boundComponentMessage?: string;
}
declare type MountOptions = Partial<MountReactComponentOptions>;
interface MountReactComponentOptions {
ReactDom: typeof react_dom;
/**
* Log the mounting command into Cypress Command Log,
* true by default.
*/
log: boolean;
/**
* Render component in React [strict mode](https://reactjs.org/docs/strict-mode.html)
* It activates additional checks and warnings for child components.
*/
strict: boolean;
}
interface MountReturn {
/**
* The component that was rendered.
*/
component: React__default.ReactNode;
/**
* Rerenders the specified component with new props. This allows testing of components that store state (`setState`)
* or have asynchronous updates (`useEffect`, `useLayoutEffect`).
*/
rerender: (component: React__default.ReactNode) => globalThis.Cypress.Chainable<MountReturn>;
/**
* Removes the mounted component.
*
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
unmount: (payload: UnmountArgs) => void;
}
/**
* Mounts a React component into the DOM.
* @param {import('react').JSX.Element} jsx The React component to mount.
* @param {MountOptions} options Options to pass to the mount function.
* @param {string} rerenderKey A key to use to force a rerender.
*
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*
* @see {@link https://on.cypress.io/mounting-react} for more details.
*
* @returns {Cypress.Chainable<MountReturn>} The mounted component.
*/
declare function mount(jsx: React__default.ReactNode, options?: MountOptions, rerenderKey?: string): Cypress.Chainable<MountReturn>;
/**
* Removed as of Cypress 11.0.0.
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
*/
declare function unmount(options?: UnmountArgs): void;
export { MountOptions, MountReturn, getContainerEl, mount, unmount };

View File

@ -0,0 +1,61 @@
{
"name": "@cypress/react18",
"version": "0.0.0-development",
"description": "Test React components using Cypress",
"main": "dist/cypress-react.cjs.js",
"scripts": {
"build": "rimraf dist && rollup -c rollup.config.mjs",
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
"build-prod": "yarn build",
"watch": "yarn build --watch --watch.exclude ./dist/**/*",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, ."
},
"devDependencies": {
"@cypress/mount-utils": "0.0.0-development",
"@cypress/react": "0.0.0-development",
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-node-resolve": "^11.1.1",
"@types/react": "^16",
"@types/react-dom": "^16",
"cypress": "0.0.0-development",
"react": "^16",
"react-dom": "^16",
"rollup": "3.7.3",
"rollup-plugin-typescript2": "^0.29.0",
"typescript": "^4.7.4"
},
"peerDependencies": {
"@types/react": "^18",
"@types/react-dom": "^18",
"cypress": "*",
"react": "^18",
"react-dom": "^18"
},
"files": [
"dist"
],
"types": "dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/react18/#readme",
"bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Freact18&template=1-bug-report.md&title=",
"keywords": [
"react",
"cypress",
"cypress-io",
"test",
"testing"
],
"module": "dist/cypress-react.esm-bundler.js",
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"publishConfig": {
"access": "public"
}
}

15
CyLukTs/lukan/node_modules/cypress/svelte/README.md generated vendored Normal file
View File

@ -0,0 +1,15 @@
# @cypress/svelte
Mount Svelte components in the open source [Cypress.io](https://www.cypress.io/) test runner **v10.7.0+**
> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Svelte Component Testing Docs](https://docs.cypress.io/guides/component-testing/svelte/overview) for mounting Svelte components. Installing and importing `mount` from `@cypress/svelte` should only be done for advanced use-cases.
## Development
Run `yarn build` to compile and sync packages to the `cypress` cli package.
Run `yarn cy:open` to open Cypress component testing against real-world examples.
Run `yarn test` to execute headless Cypress tests.
## [Changelog](./CHANGELOG.md)

View File

@ -0,0 +1,122 @@
/**
* @cypress/svelte v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
'use strict';
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
const DEFAULT_COMP_NAME = 'unknown';
let componentInstance;
const cleanup = () => {
componentInstance === null || componentInstance === void 0 ? void 0 : componentInstance.$destroy();
};
// Extract the component name from the object passed to mount
const getComponentDisplayName = (Component) => {
if (Component.name) {
const [, match] = /Proxy\<(\w+)\>/.exec(Component.name) || [];
return match || Component.name;
}
return DEFAULT_COMP_NAME;
};
/**
* Mounts a Svelte component inside the Cypress browser
*
* @param {SvelteConstructor<T>} Component Svelte component being mounted
* @param {MountReturn<T extends SvelteComponent>} options options to customize the component being mounted
* @returns Cypress.Chainable<MountReturn>
*
* @example
* import Counter from './Counter.svelte'
* import { mount } from 'cypress/svelte'
*
* it('should render', () => {
* mount(Counter, { props: { count: 42 } })
* cy.get('button').contains(42)
* })
*
* @see {@link https://on.cypress.io/mounting-svelte} for more details.
*/
function mount(Component, options = {}) {
checkForRemovedStyleOptions(options);
return cy.then(() => {
// Remove last mounted component if cy.mount is called more than once in a test
cleanup();
const target = getContainerEl();
const ComponentConstructor = (Component.default || Component);
componentInstance = new ComponentConstructor(Object.assign({ target }, options));
// by waiting, we are delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
return cy.wait(0, { log: false }).then(() => {
if (options.log !== false) {
const mountMessage = `<${getComponentDisplayName(Component)} ... />`;
Cypress.log({
name: 'mount',
message: [mountMessage],
});
}
})
.wrap({ component: componentInstance }, { log: false });
});
}
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
setupHooks(cleanup);
exports.mount = mount;

View File

@ -0,0 +1,120 @@
/**
* @cypress/svelte v0.0.0-development
* (c) 2023 Cypress.io
* Released under the MIT License
*/
const ROOT_SELECTOR = '[data-cy-root]';
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
const getContainerEl = () => {
const el = document.querySelector(ROOT_SELECTOR);
if (el) {
return el;
}
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`);
};
function checkForRemovedStyleOptions(mountingOptions) {
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
if (mountingOptions[key]) {
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
}
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
function setupHooks(optionalCallback) {
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {
return;
}
// When running component specs, we cannot allow "cy.visit"
// because it will wipe out our preparation work, and does not make much sense
// thus we overwrite "cy.visit" to throw an error
Cypress.Commands.overwrite('visit', () => {
throw new Error('cy.visit from a component spec is not allowed');
});
Cypress.Commands.overwrite('session', () => {
throw new Error('cy.session from a component spec is not allowed');
});
Cypress.Commands.overwrite('origin', () => {
throw new Error('cy.origin from a component spec is not allowed');
});
// @ts-ignore
Cypress.on('test:before:run', () => {
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
});
}
const DEFAULT_COMP_NAME = 'unknown';
let componentInstance;
const cleanup = () => {
componentInstance === null || componentInstance === void 0 ? void 0 : componentInstance.$destroy();
};
// Extract the component name from the object passed to mount
const getComponentDisplayName = (Component) => {
if (Component.name) {
const [, match] = /Proxy\<(\w+)\>/.exec(Component.name) || [];
return match || Component.name;
}
return DEFAULT_COMP_NAME;
};
/**
* Mounts a Svelte component inside the Cypress browser
*
* @param {SvelteConstructor<T>} Component Svelte component being mounted
* @param {MountReturn<T extends SvelteComponent>} options options to customize the component being mounted
* @returns Cypress.Chainable<MountReturn>
*
* @example
* import Counter from './Counter.svelte'
* import { mount } from 'cypress/svelte'
*
* it('should render', () => {
* mount(Counter, { props: { count: 42 } })
* cy.get('button').contains(42)
* })
*
* @see {@link https://on.cypress.io/mounting-svelte} for more details.
*/
function mount(Component, options = {}) {
checkForRemovedStyleOptions(options);
return cy.then(() => {
// Remove last mounted component if cy.mount is called more than once in a test
cleanup();
const target = getContainerEl();
const ComponentConstructor = (Component.default || Component);
componentInstance = new ComponentConstructor(Object.assign({ target }, options));
// by waiting, we are delaying test execution for the next tick of event loop
// and letting hooks and component lifecycle methods to execute mount
return cy.wait(0, { log: false }).then(() => {
if (options.log !== false) {
const mountMessage = `<${getComponentDisplayName(Component)} ... />`;
Cypress.log({
name: 'mount',
message: [mountMessage],
});
}
})
.wrap({ component: componentInstance }, { log: false });
});
}
// Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
// by creating an explicit function/import that the user can register in their 'component.js' support file,
// such as:
// import 'cypress/<my-framework>/support'
// or
// import { registerCT } from 'cypress/<my-framework>'
// registerCT()
// Note: This would be a breaking change
setupHooks(cleanup);
export { mount };

View File

@ -0,0 +1,201 @@
/// <reference types="cypress" />
declare module '*.svelte' {
export { SvelteComponentDev as default } from 'svelte/internal';
}
/**
* INTERNAL, DO NOT USE. Code may change at any time.
*/
interface Fragment {
key: string | null;
first: null;
c: () => void;
l: (nodes: any) => void;
h: () => void;
m: (target: HTMLElement, anchor: any) => void;
p: (ctx: any, dirty: any) => void;
r: () => void;
f: () => void;
a: () => void;
i: (local: any) => void;
o: (local: any) => void;
d: (detaching: 0 | 1) => void;
}
interface T$$ {
dirty: number[];
ctx: null | any;
bound: any;
update: () => void;
callbacks: any;
after_update: any[];
props: Record<string, 0 | string>;
fragment: null | false | Fragment;
not_equal: any;
before_update: any[];
context: Map<any, any>;
on_mount: any[];
on_destroy: any[];
skip_bound: boolean;
on_disconnect: any[];
root: Element | ShadowRoot;
}
/**
* Base class for Svelte components. Used when dev=false.
*/
declare class SvelteComponent {
$$: T$$;
$$set?: ($$props: any) => void;
$destroy(): void;
$on(type: any, callback: any): () => void;
$set($$props: any): void;
}
declare type Props = Record<string, any>;
interface ComponentConstructorOptions<Props extends Record<string, any> = Record<string, any>> {
target: Element | ShadowRoot;
anchor?: Element;
props?: Props;
context?: Map<any, any>;
hydrate?: boolean;
intro?: boolean;
$$inline?: boolean;
}
interface SvelteComponentDev$1 {
$set(props?: Props): void;
$on(event: string, callback: (event: any) => void): () => void;
$destroy(): void;
[accessor: string]: any;
}
/**
* Base class for Svelte components with some minor dev-enhancements. Used when dev=true.
*/
declare class SvelteComponentDev$1 extends SvelteComponent {
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$prop_def: Props;
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$events_def: any;
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$slot_def: any;
constructor(options: ComponentConstructorOptions);
$capture_state(): void;
$inject_state(): void;
}
interface SvelteComponentTyped<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any> {
$set(props?: Partial<Props>): void;
$on<K extends Extract<keyof Events, string>>(type: K, callback: (e: Events[K]) => void): () => void;
$destroy(): void;
[accessor: string]: any;
}
/**
* Base class to create strongly typed Svelte components.
* This only exists for typing purposes and should be used in `.d.ts` files.
*
* ### Example:
*
* You have component library on npm called `component-library`, from which
* you export a component called `MyComponent`. For Svelte+TypeScript users,
* you want to provide typings. Therefore you create a `index.d.ts`:
* ```ts
* import { SvelteComponentTyped } from "svelte";
* export class MyComponent extends SvelteComponentTyped<{foo: string}> {}
* ```
* Typing this makes it possible for IDEs like VS Code with the Svelte extension
* to provide intellisense and to use the component like this in a Svelte file
* with TypeScript:
* ```svelte
* <script lang="ts">
* import { MyComponent } from "component-library";
* </script>
* <MyComponent foo={'bar'} />
* ```
*
* #### Why not make this part of `SvelteComponent(Dev)`?
* Because
* ```ts
* class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}
* const component: typeof SvelteComponent = ASubclassOfSvelteComponent;
* ```
* will throw a type error, so we need to separate the more strictly typed class.
*/
declare class SvelteComponentTyped<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any> extends SvelteComponentDev$1 {
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$prop_def: Props;
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$events_def: Events;
/**
* @private
* For type checking capabilities only.
* Does not exist at runtime.
* ### DO NOT USE!
*/
$$slot_def: Slots;
constructor(options: ComponentConstructorOptions<Props>);
}
/**
* Convenience type to get the props the given component expects. Example:
* ```html
* <script lang="ts">
* import type { ComponentProps } from 'svelte';
* import Component from './Component.svelte';
*
* const props: ComponentProps<Component> = { foo: 'bar' }; // Errors if these aren't the correct props
* </script>
* ```
*/
declare type ComponentProps<Component extends SvelteComponent> = Component extends SvelteComponentTyped<infer Props> ? Props : never;
declare type SvelteConstructor<T> = new (...args: any[]) => T;
declare type SvelteComponentOptions<T extends SvelteComponentDev$1> = Omit<ComponentConstructorOptions<ComponentProps<T>>, 'hydrate' | 'target' | '$$inline'>;
interface MountOptions<T extends SvelteComponentDev$1> extends SvelteComponentOptions<T> {
log?: boolean;
}
interface MountReturn<T extends SvelteComponentDev$1> {
component: T;
}
/**
* Mounts a Svelte component inside the Cypress browser
*
* @param {SvelteConstructor<T>} Component Svelte component being mounted
* @param {MountReturn<T extends SvelteComponent>} options options to customize the component being mounted
* @returns Cypress.Chainable<MountReturn>
*
* @example
* import Counter from './Counter.svelte'
* import { mount } from 'cypress/svelte'
*
* it('should render', () => {
* mount(Counter, { props: { count: 42 } })
* cy.get('button').contains(42)
* })
*
* @see {@link https://on.cypress.io/mounting-svelte} for more details.
*/
declare function mount<T extends SvelteComponentDev$1>(Component: SvelteConstructor<T>, options?: MountOptions<T>): Cypress.Chainable<MountReturn<T>>;
export { MountOptions, MountReturn, mount };

44
CyLukTs/lukan/node_modules/cypress/svelte/package.json generated vendored Normal file
View File

@ -0,0 +1,44 @@
{
"name": "@cypress/svelte",
"version": "0.0.0-development",
"description": "Browser-based Component Testing for Svelte.js with Cypress.io 🧡",
"main": "dist/cypress-svelte.cjs.js",
"scripts": {
"prebuild": "rimraf dist",
"build": "rollup -c rollup.config.mjs",
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
"build-prod": "yarn build",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, .",
"check-ts": "tsc --noEmit"
},
"devDependencies": {
"@cypress/mount-utils": "0.0.0-development",
"svelte": "^3.49.0",
"typescript": "^4.7.4"
},
"peerDependencies": {
"cypress": ">=10.6.0",
"svelte": ">=3.0.0"
},
"files": [
"dist/**/*"
],
"types": "dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cypress-io/cypress.git"
},
"homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/svelte/#readme",
"bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Fsvelte&template=1-bug-report.md&title=",
"keywords": [
"cypress",
"svelte",
"testing",
"component testing"
],
"module": "dist/cypress-svelte.esm-bundler.js",
"publishConfig": {
"access": "public"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1956
CyLukTs/lukan/node_modules/cypress/types/chai/index.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
// so that Cypress can get and use the Blob type
// tslint:disable-next-line:no-implicit-dependencies
import * as blobUtil from 'blob-util'
export = BlobUtil
export as namespace BlobUtil
declare namespace BlobUtil {
type BlobUtilStatic = typeof blobUtil
}

View File

@ -0,0 +1,12 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
// so that Cypress can get and use the Blob type
import ImportedBluebird = require('./bluebird')
export = Bluebird
export as namespace Bluebird
declare namespace Bluebird {
type BluebirdStatic = typeof ImportedBluebird
interface Promise<T> extends ImportedBluebird<T> {}
}

10
CyLukTs/lukan/node_modules/cypress/types/cy-chai.d.ts generated vendored Normal file
View File

@ -0,0 +1,10 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
/// <reference path="./chai/index.d.ts" />
declare namespace Chai {
interface Include {
html(html: string): Assertion
text(text: string): Assertion
value(text: string): Assertion
}
}

13
CyLukTs/lukan/node_modules/cypress/types/cy-http.d.ts generated vendored Normal file
View File

@ -0,0 +1,13 @@
/**
* This file should be deleted as soon as the serever
* TODO: delete this file when ResolvedDevServerConfig.server is converted to closeServer
*/
/// <reference types="node" />
import * as cyUtilsHttp from 'http'
export = cyUtilsHttp
/**
* namespace created to bridge nodeJs.http typings so that
* we can type http Server in CT
*/
export as namespace cyUtilsHttp

View File

@ -0,0 +1,96 @@
// I was trying to avoid relying on "import" of actual module from "minimatch"
// because it would not work in test project, and the only reliable way
// to get around type errors finally was to copy the minimal minimatch function
// definition from "minimatch/index.d.ts" here and just keep it in our code
export = Minimatch
export as namespace Minimatch
interface MinimatchOptions {
/**
* Dump a ton of stuff to stderr.
*
* @default false
*/
debug?: boolean
/**
* Do not expand {a,b} and {1..3} brace sets.
*
* @default false
*/
nobrace?: boolean
/**
* Disable ** matching against multiple folder names.
*
* @default false
*/
noglobstar?: boolean
/**
* Allow patterns to match filenames starting with a period,
* even if the pattern does not explicitly have a period in that spot.
*
* @default false
*/
dot?: boolean
/**
* Disable "extglob" style patterns like +(a|b).
*
* @default false
*/
noext?: boolean
/**
* Perform a case-insensitive match.
*
* @default false
*/
nocase?: boolean
/**
* When a match is not found by minimatch.match,
* return a list containing the pattern itself if this option is set.
* Otherwise, an empty list is returned if there are no matches.
*
* @default false
*/
nonull?: boolean
/**
* If set, then patterns without slashes will be matched against
* the basename of the path if it contains slashes.
*
* @default false
*/
matchBase?: boolean
/**
* Suppress the behavior of treating #
* at the start of a pattern as a comment.
*
* @default false
*/
nocomment?: boolean
/**
* Suppress the behavior of treating a leading ! character as negation.
*
* @default false
*/
nonegate?: boolean
/**
* Returns from negate expressions the same as if they were not negated.
* (Ie, true on a hit, false on a miss.)
*
* @default false
*/
flipNegate?: boolean
}
declare namespace Minimatch {
function minimatch(target: string, pattern: string, options?: MinimatchOptions): boolean
}

View File

@ -0,0 +1,33 @@
// Cypress, cy, Log inherits EventEmitter.
type EventEmitter2 = import("eventemitter2").EventEmitter2
interface CyEventEmitter extends Omit<EventEmitter2, 'waitFor'> {
proxyTo: (cy: Cypress.cy) => null
emitMap: (eventName: string, args: any[]) => Array<(...args: any[]) => any>
emitThen: (eventName: string, args: any[]) => Bluebird.BluebirdStatic
}
// Copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/events.d.ts
// to avoid type conflict.
interface NodeEventEmitter {
addListener(event: string | symbol, listener: (...args: any[]) => void): this
on(event: string | symbol, listener: (...args: any[]) => void): this
once(event: string | symbol, listener: (...args: any[]) => void): this
removeListener(event: string | symbol, listener: (...args: any[]) => void): this
off(event: string | symbol, listener: (...args: any[]) => void): this
removeAllListeners(event?: string | symbol): this
setMaxListeners(n: number): this
getMaxListeners(): number
listeners(event: string | symbol): Array<(...args: any[]) => void>
rawListeners(event: string | symbol): Array<(...args: any[]) => void>
emit(event: string | symbol, ...args: any[]): boolean
listenerCount(type: string | symbol): number
// Added in Node 6...
prependListener(event: string | symbol, listener: (...args: any[]) => void): this
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this
eventNames(): Array<string | symbol>
}
// We use the Buffer class for dealing with binary data, especially around the
// selectFile interface.
type BufferType = typeof import("buffer/").Buffer

View File

@ -0,0 +1,3 @@
// Cypress adds chai expect and assert to global
declare const expect: Chai.ExpectStatic
declare const assert: Chai.AssertStatic

View File

@ -0,0 +1,22 @@
/**
* Global variables `cy` added by Cypress with all API commands.
* @see https://on.cypress.io/api
*
```
cy.get('button').click()
cy.get('.result').contains('Expected text')
```
*/
declare const cy: Cypress.cy & CyEventEmitter
/**
* Global variable `Cypress` holds common utilities and constants.
* @see https://on.cypress.io/api
*
```
Cypress.config("pageLoadTimeout") // => 60000
Cypress.version // => "1.4.0"
Cypress._ // => Lodash _
```
*/
declare const Cypress: Cypress.Cypress & CyEventEmitter

View File

@ -0,0 +1,420 @@
//
// Cypress NPM api type declarations
// https://on.cypress.io/module-api
// https://github.com/cypress-io/cypress/issues/2141
//
// in the future the NPM module itself will be in TypeScript
// but for now describe it as an ambient module
declare namespace CypressCommandLine {
type HookName = 'before' | 'beforeEach' | 'afterEach' | 'after'
interface TestError {
name: string
message: string
stack: string
}
/**
* All options that one can pass to "cypress.run"
* @see https://on.cypress.io/module-api#cypress-run
* @example
```
const cypress = require('cypress')
cypress.run({
reporter: 'junit',
browser: 'chrome',
config: {
baseUrl: 'http://localhost:8080',
chromeWebSecurity: false,
},
env: {
foo: 'bar',
baz: 'quux',
}
})
```
*/
interface CypressRunOptions extends CypressCommonOptions {
/**
* Specify browser to run tests in, either by name or by filesystem path
*/
browser: string
/**
* Specify a unique identifier for a run to enable grouping or parallelization
*/
ciBuildId: string
/**
* Group recorded tests together under a single run name
*/
group: string
/**
* Tag string for the recorded run, like "production,nightly"
*/
tag: string
/**
* Display the browser instead of running headlessly
*/
headed: boolean
/**
* Hide the browser instead of running headed
*/
headless: boolean
/**
* Specify your secret Record Key
*/
key: string
/**
* Keep Cypress open after all tests run
*/
noExit: boolean
/**
* Run recorded specs in parallel across multiple machines
*/
parallel: boolean
/**
* Override default port
*/
port: number
/**
* Run quietly, using only the configured reporter
*/
quiet: boolean
/**
* Whether to record the test run
*/
record: boolean
/**
* Specify a mocha reporter
*/
reporter: string
/**
* Specify mocha reporter options
*/
reporterOptions: any
/**
* Specify the specs to run
*/
spec: string
/**
* Specify the number of failures to cancel a run being recorded to the Cloud or false to disable auto-cancellation.
*/
autoCancelAfterFailures: number | false
}
/**
* All options that one can pass to "cypress.open"
* @see https://on.cypress.io/module-api#cypress-open
* @example
```
const cypress = require('cypress')
cypress.open({
env: {
username: 'Joe Doe',
email: 'joe@acme.co'
},
project: '~/demos/my-project'
})
```
*/
interface CypressOpenOptions extends CypressCommonOptions {
/**
* Specify browser to run tests in, either by name or by filesystem path
*/
browser: string
/**
* Open Cypress in detached mode
*/
detached: boolean
/**
* Run in global mode
*/
global: boolean
/**
* Override default port
*/
port: number
}
/**
* Options available for `cypress.open` and `cypress.run`
*/
interface CypressCommonOptions {
/**
* Specify configuration
*/
config: Cypress.ConfigOptions
/**
* Path to the config file to be used.
*
* @default "cypress.config.{js,ts,mjs,cjs}"
*/
configFile: string
/**
* Specify environment variables.
* TODO: isn't this duplicate of config.env?!
*/
env: object
/**
* Path to a specific project
*/
project: string
/**
* Specify the type of tests to execute.
* @default "e2e"
*/
testingType: Cypress.TestingType
}
// small utility types to better express meaning of other types
type dateTimeISO = string
type ms = number
type pixels = number
/**
* Cypress single test result
*/
interface TestResult {
title: string[]
state: string
body: string
/**
* Error string as it's presented in console if the test fails
*/
displayError: string | null
attempts: AttemptResult[]
}
interface AttemptResult {
state: string
error: TestError | null
startedAt: dateTimeISO
duration: ms
videoTimestamp: ms
screenshots: ScreenshotInformation[]
}
/**
* Information about a single "before", "beforeEach", "afterEach" and "after" hook.
*/
interface HookInformation {
hookName: HookName
title: string[]
body: string
}
/**
* Information about a single screenshot.
*/
interface ScreenshotInformation {
name: string
takenAt: dateTimeISO
/**
* Absolute path to the saved image
*/
path: string
height: pixels
width: pixels
}
/**
* Cypress test run result for a single spec.
*/
interface RunResult {
/**
* Accurate test results collected by Cypress.
*/
stats: {
suites: number
tests: number
passes: number
pending: number
skipped: number
failures: number
startedAt: dateTimeISO
endedAt: dateTimeISO
duration: ms
wallClockDuration?: number
}
/**
* Reporter name like "spec"
*/
reporter: string
/**
* This is controlled by the reporter, and Cypress cannot guarantee
* the properties. Usually this object has suites, tests, passes, etc
*/
reporterStats: object
hooks: HookInformation[]
tests: TestResult[]
error: string | null
video: string | null
/**
* information about the spec test file.
*/
spec: {
/**
* filename like "spec.js"
*/
name: string
/**
* name relative to the project root, like "cypress/integration/spec.js"
*/
relative: string
/**
* resolved filename of the spec
*/
absolute: string
relativeToCommonRoot: string
}
shouldUploadVideo: boolean
skippedSpec: boolean
}
/**
* Results returned by the test run.
* @see https://on.cypress.io/module-api
*/
interface CypressRunResult {
status: 'finished'
startedTestsAt: dateTimeISO
endedTestsAt: dateTimeISO
totalDuration: ms
totalSuites: number
totalTests: number
totalFailed: number
totalPassed: number
totalPending: number
totalSkipped: number
/**
* If Cypress test run is being recorded, full url will be provided.
* @see https://on.cypress.io/dashboard-introduction
*/
runUrl?: string
runs: RunResult[]
browserPath: string
browserName: string
browserVersion: string
osName: string
osVersion: string
cypressVersion: string
config: Cypress.ResolvedConfigOptions
}
/**
* If Cypress fails to run at all (for example, if there are no spec files to run),
* then it will return a CypressFailedRunResult. Check the failures attribute.
* @example
```
const result = await cypress.run()
if (result.status === 'failed') {
console.error('failures %d', result.failures)
console.error(result.message)
process.exit(result.failures)
}
```
*
**/
interface CypressFailedRunResult {
status: 'failed'
failures: number
message: string
}
/**
* Methods allow parsing given CLI arguments the same way Cypress CLI does it.
*/
interface CypressCliParser {
/**
* Parses the given array of string arguments to "cypress run"
* just like Cypress CLI does it.
* @see https://on.cypress.io/module-api
* @example
* const cypress = require('cypress')
* const args = ['cypress', 'run', '--browser', 'chrome']
* const options = await cypress.cli.parseRunArguments(args)
* // options is {browser: 'chrome'}
* // pass the options to cypress.run()
* const results = await cypress.run(options)
*/
parseRunArguments(args: string[]): Promise<Partial<CypressRunOptions>>
}
}
declare module 'cypress' {
/**
* Cypress NPM module interface.
* @see https://on.cypress.io/module-api
* @example
```
const cypress = require('cypress')
cypress.run().then(results => ...)
```
*/
interface CypressNpmApi {
/**
* Execute a headless Cypress test run.
* @see https://on.cypress.io/module-api#cypress-run
* @example
```
const cypress = require('cypress')
// runs all spec files matching a wildcard
cypress.run({
spec: 'cypress/integration/admin*-spec.js'
}).then(results => {
if (results.status === 'failed') {
// Cypress could not run
} else {
// inspect results object
}
})
```
*/
run(options?: Partial<CypressCommandLine.CypressRunOptions>): Promise<CypressCommandLine.CypressRunResult | CypressCommandLine.CypressFailedRunResult>
/**
* Opens Cypress GUI. Resolves with void when the
* GUI is closed.
* @see https://on.cypress.io/module-api#cypress-open
*/
open(options?: Partial<CypressCommandLine.CypressOpenOptions>): Promise<void>
/**
* Utility functions for parsing CLI arguments the same way
* Cypress does
*/
cli: CypressCommandLine.CypressCliParser
/**
* Provides automatic code completion for configuration in many popular code editors.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your config object with `defineConfig()`
* @example
* module.exports = defineConfig({
* viewportWith: 400
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ConfigOptions} config
* @returns {Cypress.ConfigOptions} the configuration passed in parameter
*/
defineConfig<ComponentDevServerOpts = any>(config: Cypress.ConfigOptions<ComponentDevServerOpts>): Cypress.ConfigOptions
/**
* Provides automatic code completion for Component Frameworks Definitions.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your Component Framework Definition object with `defineComponentFramework()`
* @example
* module.exports = defineComponentFramework({
* type: 'cypress-ct-solid-js'
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ThirdPartyComponentFrameworkDefinition} config
* @returns {Cypress.ThirdPartyComponentFrameworkDefinition} the configuration passed in parameter
*/
defineComponentFramework(config: Cypress.ThirdPartyComponentFrameworkDefinition): Cypress.ThirdPartyComponentFrameworkDefinition
}
// export Cypress NPM module interface
const cypress: CypressNpmApi
export = cypress
}

View File

@ -0,0 +1,4 @@
// type helpers
declare namespace Cypress {
type Nullable<T> = T | null
}

6514
CyLukTs/lukan/node_modules/cypress/types/cypress.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

33
CyLukTs/lukan/node_modules/cypress/types/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,33 @@
// Project: https://www.cypress.io
// GitHub: https://github.com/cypress-io/cypress
// Definitions by: Gert Hengeveld <https://github.com/ghengeveld>
// Mike Woudenberg <https://github.com/mikewoudenberg>
// Robbert van Markus <https://github.com/rvanmarkus>
// Nicholas Boll <https://github.com/nicholasboll>
// TypeScript Version: 3.4
// Updated by the Cypress team: https://www.cypress.io/about/
/// <reference path="./cy-blob-util.d.ts" />
/// <reference path="./cy-bluebird.d.ts" />
/// <reference path="./cy-minimatch.d.ts" />
/// <reference path="./cy-chai.d.ts" />
/// <reference path="./lodash/index.d.ts" />
/// <reference path="./sinon/index.d.ts" />
/// <reference path="./sinon-chai/index.d.ts" />
/// <reference path="./mocha/index.d.ts" />
/// <reference path="./jquery/index.d.ts" />
/// <reference path="./chai-jquery/index.d.ts" />
// jQuery includes dependency "sizzle" that provides types
// so we include it too in "node_modules/sizzle".
// This way jQuery can load it using 'reference types="sizzle"' directive
// load ambient declaration for "cypress" NPM module
// hmm, how to load it better?
/// <reference path="./cypress-npm-api.d.ts" />
/// <reference path="./net-stubbing.d.ts" />
/// <reference path="./cypress.d.ts" />
/// <reference path="./cypress-global-vars.d.ts" />
/// <reference path="./cypress-type-helpers.d.ts" />
/// <reference path="./cypress-expect.d.ts" />

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
// Type definitions for jquery 3.3
// Project: https://jquery.com
// Definitions by: Leonard Thieu <https://github.com/leonard-thieu>
// Boris Yankov <https://github.com/borisyankov>
// Christian Hoffmeister <https://github.com/choffmeister>
// Steve Fenton <https://github.com/Steve-Fenton>
// Diullei Gomes <https://github.com/Diullei>
// Tass Iliopoulos <https://github.com/tasoili>
// Jason Swearingen <https://github.com/jasons-novaleaf>
// Sean Hill <https://github.com/seanski>
// Guus Goossens <https://github.com/Guuz>
// Kelly Summerlin <https://github.com/ksummerlin>
// Basarat Ali Syed <https://github.com/basarat>
// Nicholas Wolverson <https://github.com/nwolverson>
// Derek Cicerone <https://github.com/derekcicerone>
// Andrew Gaspar <https://github.com/AndrewGaspar>
// Seikichi Kondo <https://github.com/seikichi>
// Benjamin Jackman <https://github.com/benjaminjackman>
// Poul Sorensen <https://github.com/s093294>
// Josh Strobl <https://github.com/JoshStrobl>
// John Reilly <https://github.com/johnnyreilly>
// Dick van den Brink <https://github.com/DickvdBrink>
// Thomas Schulz <https://github.com/King2500>
// Terry Mun <https://github.com/terrymun>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
/// <reference types="sizzle" />
/// <reference path="JQueryStatic.d.ts" />
/// <reference path="JQuery.d.ts" />
/// <reference path="misc.d.ts" />
/// <reference path="legacy.d.ts" />
export = jQuery;

View File

@ -0,0 +1,204 @@
// tslint:disable:no-irregular-whitespace
// tslint:disable-next-line:no-empty-interface
interface JQueryCallback extends JQuery.Callbacks { }
interface JQueryDeferred<T> extends JQuery.Deferred<T> { }
// tslint:disable-next-line:no-empty-interface
interface JQueryEventConstructor extends JQuery.EventStatic { }
interface JQueryDeferred<T> extends JQuery.Deferred<T> { }
// tslint:disable-next-line:no-empty-interface
interface JQueryAjaxSettings extends JQuery.AjaxSettings { }
interface JQueryAnimationOptions extends JQuery.EffectsOptions<Element> { }
// tslint:disable-next-line:no-empty-interface
interface JQueryCoordinates extends JQuery.Coordinates { }
interface JQueryGenericPromise<T> extends JQuery.Thenable<T> { }
// tslint:disable-next-line:no-empty-interface
interface JQueryXHR extends JQuery.jqXHR { }
interface JQueryPromise<T> extends JQuery.Promise<T> { }
// tslint:disable-next-line:no-empty-interface
interface JQuerySerializeArrayElement extends JQuery.NameValuePair { }
/**
* @deprecated Deprecated since 1.9. See \`{@link https://api.jquery.com/jQuery.support/ }\`.
*/
// tslint:disable-next-line:no-empty-interface
interface JQuerySupport extends JQuery.PlainObject { }
// Legacy types that are not represented in the current type definitions are marked deprecated.
/**
* @deprecated Deprecated. Use \`{@link JQuery.Deferred.Callback }\` or \`{@link JQuery.Deferred.CallbackBase }\`.
*/
interface JQueryPromiseCallback<T> {
// tslint:disable-next-line:callable-types
(value?: T, ...args: any[]): void;
}
/**
* @deprecated Deprecated. Use \`{@link JQueryStatic.param JQueryStatic&#91;'param'&#93;}\`.
*/
interface JQueryParam {
/**
* Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request.
* @param obj An array or object to serialize.
* @param traditional A Boolean indicating whether to perform a traditional "shallow" serialization.
*/
// tslint:disable-next-line:callable-types
(obj: any, traditional?: boolean): string;
}
/**
* @deprecated Deprecated. Use \`{@link JQuery.Event }\`.
*/
interface BaseJQueryEventObject extends Event {
/**
* The current DOM element within the event bubbling phase.
* @see \`{@link https://api.jquery.com/event.currentTarget/ }\`
*/
currentTarget: Element;
/**
* An optional object of data passed to an event method when the current executing handler is bound.
* @see \`{@link https://api.jquery.com/event.data/ }\`
*/
data: any;
/**
* The element where the currently-called jQuery event handler was attached.
* @see \`{@link https://api.jquery.com/event.delegateTarget/ }\`
*/
delegateTarget: Element;
/**
* Returns whether event.preventDefault() was ever called on this event object.
* @see \`{@link https://api.jquery.com/event.isDefaultPrevented/ }\`
*/
isDefaultPrevented(): boolean;
/**
* Returns whether event.stopImmediatePropagation() was ever called on this event object.
* @see \`{@link https://api.jquery.com/event.isImmediatePropagationStopped/ }\`
*/
isImmediatePropagationStopped(): boolean;
/**
* Returns whether event.stopPropagation() was ever called on this event object.
* @see \`{@link https://api.jquery.com/event.isPropagationStopped/ }\`
*/
isPropagationStopped(): boolean;
/**
* The namespace specified when the event was triggered.
* @see \`{@link https://api.jquery.com/event.namespace/ }\`
*/
namespace: string;
/**
* The browser's original Event object.
* @see \`{@link https://api.jquery.com/category/events/event-object/ }\`
*/
originalEvent: Event;
/**
* If this method is called, the default action of the event will not be triggered.
* @see \`{@link https://api.jquery.com/event.preventDefault/ }\`
*/
preventDefault(): any;
/**
* The other DOM element involved in the event, if any.
* @see \`{@link https://api.jquery.com/event.relatedTarget/ }\`
*/
relatedTarget: Element;
/**
* The last value returned by an event handler that was triggered by this event, unless the value was undefined.
* @see \`{@link https://api.jquery.com/event.result/ }\`
*/
result: any;
/**
* Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.
* @see \`{@link https://api.jquery.com/event.stopImmediatePropagation/ }\`
*/
stopImmediatePropagation(): void;
/**
* Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
* @see \`{@link https://api.jquery.com/event.stopPropagation/ }\`
*/
stopPropagation(): void;
/**
* The DOM element that initiated the event.
* @see \`{@link https://api.jquery.com/event.target/ }\`
*/
target: Element;
/**
* The mouse position relative to the left edge of the document.
* @see \`{@link https://api.jquery.com/event.pageX/ }\`
*/
pageX: number;
/**
* The mouse position relative to the top edge of the document.
* @see \`{@link https://api.jquery.com/event.pageY/ }\`
*/
pageY: number;
/**
* For key or mouse events, this property indicates the specific key or button that was pressed.
* @see \`{@link https://api.jquery.com/event.which/ }\`
*/
which: number;
/**
* Indicates whether the META key was pressed when the event fired.
* @see \`{@link https://api.jquery.com/event.metaKey/ }\`
*/
metaKey: boolean;
}
/**
* @deprecated Deprecated. Use \`{@link JQuery.Event }\`.
*/
interface JQueryInputEventObject extends BaseJQueryEventObject {
altKey: boolean;
ctrlKey: boolean;
metaKey: boolean;
shiftKey: boolean;
}
/**
* @deprecated Deprecated. Use \`{@link JQuery.Event }\`.
*/
interface JQueryMouseEventObject extends JQueryInputEventObject {
button: number;
clientX: number;
clientY: number;
offsetX: number;
offsetY: number;
pageX: number;
pageY: number;
screenX: number;
screenY: number;
}
/**
* @deprecated Deprecated. Use \`{@link JQuery.Event }\`.
*/
interface JQueryKeyEventObject extends JQueryInputEventObject {
/** @deprecated */
char: string;
/** @deprecated */
charCode: number;
key: string;
/** @deprecated */
keyCode: number;
}
/**
* @deprecated Deprecated. Use \`{@link JQuery.Event }\`.
*/
interface JQueryEventObject extends BaseJQueryEventObject, JQueryInputEventObject, JQueryMouseEventObject, JQueryKeyEventObject { }
/**
* @deprecated Deprecated.
*/
interface JQueryPromiseOperator<T, U> {
// tslint:disable-next-line:callable-types
(callback1: JQuery.TypeOrArray<JQueryPromiseCallback<T>>,
...callbacksN: Array<JQuery.TypeOrArray<JQueryPromiseCallback<any>>>): JQueryPromise<U>;
}
/**
* @deprecated Deprecated. Internal. See \`{@link https://github.com/jquery/api.jquery.com/issues/912 }\`.
*/
interface JQueryEasingFunction {
// tslint:disable-next-line:callable-types
(percent: number): number;
}
/**
* @deprecated Deprecated. Internal. See \`{@link https://github.com/jquery/api.jquery.com/issues/912 }\`.
*/
interface JQueryEasingFunctions {
[name: string]: JQueryEasingFunction;
linear: JQueryEasingFunction;
swing: JQueryEasingFunction;
}

6661
CyLukTs/lukan/node_modules/cypress/types/jquery/misc.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
import { add } from "./index";
export = add;

View File

@ -0,0 +1,2 @@
import { after } from "./index";
export = after;

View File

@ -0,0 +1,2 @@
import { ary } from "./index";
export = ary;

View File

@ -0,0 +1,2 @@
import { assign } from "./index";
export = assign;

View File

@ -0,0 +1,2 @@
import { assignIn } from "./index";
export = assignIn;

View File

@ -0,0 +1,2 @@
import { assignInWith } from "./index";
export = assignInWith;

View File

@ -0,0 +1,2 @@
import { assignWith } from "./index";
export = assignWith;

View File

@ -0,0 +1,2 @@
import { at } from "./index";
export = at;

View File

@ -0,0 +1,2 @@
import { attempt } from "./index";
export = attempt;

View File

@ -0,0 +1,2 @@
import { before } from "./index";
export = before;

View File

@ -0,0 +1,2 @@
import { bind } from "./index";
export = bind;

View File

@ -0,0 +1,2 @@
import { bindAll } from "./index";
export = bindAll;

View File

@ -0,0 +1,2 @@
import { bindKey } from "./index";
export = bindKey;

View File

@ -0,0 +1,2 @@
import { camelCase } from "./index";
export = camelCase;

View File

@ -0,0 +1,2 @@
import { capitalize } from "./index";
export = capitalize;

View File

@ -0,0 +1,2 @@
import { castArray } from "./index";
export = castArray;

View File

@ -0,0 +1,2 @@
import { ceil } from "./index";
export = ceil;

View File

@ -0,0 +1,2 @@
import { chain } from "./index";
export = chain;

View File

@ -0,0 +1,2 @@
import { chunk } from "./index";
export = chunk;

View File

@ -0,0 +1,2 @@
import { clamp } from "./index";
export = clamp;

View File

@ -0,0 +1,2 @@
import { clone } from "./index";
export = clone;

View File

@ -0,0 +1,2 @@
import { cloneDeep } from "./index";
export = cloneDeep;

View File

@ -0,0 +1,2 @@
import { cloneDeepWith } from "./index";
export = cloneDeepWith;

View File

@ -0,0 +1,2 @@
import { cloneWith } from "./index";
export = cloneWith;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,280 @@
import _ = require("../index");
// tslint:disable-next-line:strict-export-declare-modifiers
type GlobalPartial<T> = Partial<T>;
declare module "../index" {
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type PartialObject<T> = GlobalPartial<T>;
type Many<T> = T | ReadonlyArray<T>;
type ImpChain<T> =
T extends { __trapAny: any } ? Collection<any> & Function<any> & Object<any> & Primitive<any> & String :
T extends null | undefined ? never :
T extends string | null | undefined ? String :
T extends (...args: any) => any ? Function<T> :
T extends List<infer U> | null | undefined ? Collection<U> :
T extends object | null | undefined ? Object<T> :
Primitive<T>;
type ExpChain<T> =
T extends { __trapAny: any } ? CollectionChain<any> & FunctionChain<any> & ObjectChain<any> & PrimitiveChain<any> & StringChain :
T extends null | undefined ? never :
T extends string ? StringChain :
T extends string | null | undefined ? StringNullableChain :
T extends (...args: any) => any ? FunctionChain<T> :
T extends List<infer U> | null | undefined ? CollectionChain<U> :
T extends object | null | undefined ? ObjectChain<T> :
PrimitiveChain<T>;
interface LoDashStatic {
/**
* Creates a lodash object which wraps value to enable implicit method chain sequences.
* Methods that operate on and return arrays, collections, and functions can be chained together.
* Methods that retrieve a single value or may return a primitive value will automatically end the
* chain sequence and return the unwrapped value. Otherwise, the value must be unwrapped with value().
*
* Explicit chain sequences, which must be unwrapped with value(), may be enabled using _.chain.
*
* The execution of chained methods is lazy, that is, it's deferred until value() is
* implicitly or explicitly called.
*
* Lazy evaluation allows several methods to support shortcut fusion. Shortcut fusion
* is an optimization to merge iteratee calls; this avoids the creation of intermediate
* arrays and can greatly reduce the number of iteratee executions. Sections of a chain
* sequence qualify for shortcut fusion if the section is applied to an array and iteratees
* accept only one argument. The heuristic for whether a section qualifies for shortcut
* fusion is subject to change.
*
* Chaining is supported in custom builds as long as the value() method is directly or
* indirectly included in the build.
*
* In addition to lodash methods, wrappers have Array and String methods.
* The wrapper Array methods are:
* concat, join, pop, push, shift, sort, splice, and unshift.
* The wrapper String methods are:
* replace and split.
*
* The wrapper methods that support shortcut fusion are:
* at, compact, drop, dropRight, dropWhile, filter, find, findLast, head, initial, last,
* map, reject, reverse, slice, tail, take, takeRight, takeRightWhile, takeWhile, and toArray
*
* The chainable wrapper methods are:
* after, ary, assign, assignIn, assignInWith, assignWith, at, before, bind, bindAll, bindKey,
* castArray, chain, chunk, commit, compact, concat, conforms, constant, countBy, create,
* curry, debounce, defaults, defaultsDeep, defer, delay, difference, differenceBy, differenceWith,
* drop, dropRight, dropRightWhile, dropWhile, extend, extendWith, fill, filter, flatMap,
* flatMapDeep, flatMapDepth, flatten, flattenDeep, flattenDepth, flip, flow, flowRight,
* fromPairs, functions, functionsIn, groupBy, initial, intersection, intersectionBy, intersectionWith,
* invert, invertBy, invokeMap, iteratee, keyBy, keys, keysIn, map, mapKeys, mapValues,
* matches, matchesProperty, memoize, merge, mergeWith, method, methodOf, mixin, negate,
* nthArg, omit, omitBy, once, orderBy, over, overArgs, overEvery, overSome, partial, partialRight,
* partition, pick, pickBy, plant, property, propertyOf, pull, pullAll, pullAllBy, pullAllWith, pullAt,
* push, range, rangeRight, rearg, reject, remove, rest, reverse, sampleSize, set, setWith,
* shuffle, slice, sort, sortBy, sortedUniq, sortedUniqBy, splice, spread, tail, take,
* takeRight, takeRightWhile, takeWhile, tap, throttle, thru, toArray, toPairs, toPairsIn,
* toPath, toPlainObject, transform, unary, union, unionBy, unionWith, uniq, uniqBy, uniqWith,
* unset, unshift, unzip, unzipWith, update, updateWith, values, valuesIn, without, wrap,
* xor, xorBy, xorWith, zip, zipObject, zipObjectDeep, and zipWith.
*
* The wrapper methods that are not chainable by default are:
* add, attempt, camelCase, capitalize, ceil, clamp, clone, cloneDeep, cloneDeepWith, cloneWith,
* conformsTo, deburr, defaultTo, divide, each, eachRight, endsWith, eq, escape, escapeRegExp,
* every, find, findIndex, findKey, findLast, findLastIndex, findLastKey, first, floor, forEach,
* forEachRight, forIn, forInRight, forOwn, forOwnRight, get, gt, gte, has, hasIn, head,
* identity, includes, indexOf, inRange, invoke, isArguments, isArray, isArrayBuffer,
* isArrayLike, isArrayLikeObject, isBoolean, isBuffer, isDate, isElement, isEmpty, isEqual, isEqualWith,
* isError, isFinite, isFunction, isInteger, isLength, isMap, isMatch, isMatchWith, isNaN,
* isNative, isNil, isNull, isNumber, isObject, isObjectLike, isPlainObject, isRegExp,
* isSafeInteger, isSet, isString, isUndefined, isTypedArray, isWeakMap, isWeakSet, join,
* kebabCase, last, lastIndexOf, lowerCase, lowerFirst, lt, lte, max, maxBy, mean, meanBy,
* min, minBy, multiply, noConflict, noop, now, nth, pad, padEnd, padStart, parseInt, pop,
* random, reduce, reduceRight, repeat, result, round, runInContext, sample, shift, size,
* snakeCase, some, sortedIndex, sortedIndexBy, sortedLastIndex, sortedLastIndexBy, startCase,
* startsWith, stubArray, stubFalse, stubObject, stubString, stubTrue, subtract, sum, sumBy,
* template, times, toFinite, toInteger, toJSON, toLength, toLower, toNumber, toSafeInteger,
* toString, toUpper, trim, trimEnd, trimStart, truncate, unescape, uniqueId, upperCase,
* upperFirst, value, and words.
**/
<TrapAny extends { __trapAny: any }>(value: TrapAny): Collection<any> & Function<any> & Object<any> & Primitive<any> & String;
<T extends null | undefined>(value: T): Primitive<T>;
(value: string | null | undefined): String;
<T extends (...args: any) => any>(value: T): Function<T>;
<T = any>(value: List<T> | null | undefined): Collection<T>;
<T extends object>(value: T | null | undefined): Object<T>;
<T>(value: T): Primitive<T>;
/**
* The semantic version number.
**/
VERSION: string;
/**
* By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby
* (ERB). Change the following template settings to use alternative delimiters.
**/
templateSettings: TemplateSettings;
}
/**
* By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby
* (ERB). Change the following template settings to use alternative delimiters.
**/
interface TemplateSettings {
/**
* The "escape" delimiter.
**/
escape?: RegExp;
/**
* The "evaluate" delimiter.
**/
evaluate?: RegExp;
/**
* An object to import into the template as local variables.
*/
imports?: Dictionary<any>;
/**
* The "interpolate" delimiter.
*/
interpolate?: RegExp;
/**
* Used to reference the data object in the template text.
*/
variable?: string;
}
/**
* Creates a cache object to store key/value pairs.
*/
interface MapCache {
/**
* Removes `key` and its value from the cache.
* @param key The key of the value to remove.
* @return Returns `true` if the entry was removed successfully, else `false`.
*/
delete(key: any): boolean;
/**
* Gets the cached value for `key`.
* @param key The key of the value to get.
* @return Returns the cached value.
*/
get(key: any): any;
/**
* Checks if a cached value for `key` exists.
* @param key The key of the entry to check.
* @return Returns `true` if an entry for `key` exists, else `false`.
*/
has(key: any): boolean;
/**
* Sets `value` to `key` of the cache.
* @param key The key of the value to cache.
* @param value The value to cache.
* @return Returns the cache object.
*/
set(key: any, value: any): this;
/**
* Removes all key-value entries from the map.
*/
clear?: () => void;
}
interface MapCacheConstructor {
new (): MapCache;
}
interface Collection<T> {
pop(): T | undefined;
push(...items: T[]): this;
shift(): T | undefined;
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number, ...items: T[]): this;
unshift(...items: T[]): this;
}
interface CollectionChain<T> {
pop(): ExpChain<T | undefined>;
push(...items: T[]): this;
shift(): ExpChain<T | undefined>;
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number, ...items: T[]): this;
unshift(...items: T[]): this;
}
interface Function<T extends (...args: any) => any> extends LoDashImplicitWrapper<T> {
}
interface String extends LoDashImplicitWrapper<string> {
}
interface Object<T> extends LoDashImplicitWrapper<T> {
}
interface Collection<T> extends LoDashImplicitWrapper<T[]> {
}
interface Primitive<T> extends LoDashImplicitWrapper<T> {
}
interface FunctionChain<T extends (...args: any) => any> extends LoDashExplicitWrapper<T> {
}
interface StringChain extends LoDashExplicitWrapper<string> {
}
interface StringNullableChain extends LoDashExplicitWrapper<string | undefined> {
}
interface ObjectChain<T> extends LoDashExplicitWrapper<T> {
}
interface CollectionChain<T> extends LoDashExplicitWrapper<T[]> {
}
interface PrimitiveChain<T> extends LoDashExplicitWrapper<T> {
}
type NotVoid = unknown;
type IterateeShorthand<T> = PropertyName | [PropertyName, any] | PartialShallow<T>;
type ArrayIterator<T, TResult> = (value: T, index: number, collection: T[]) => TResult;
type ListIterator<T, TResult> = (value: T, index: number, collection: List<T>) => TResult;
type ListIteratee<T> = ListIterator<T, NotVoid> | IterateeShorthand<T>;
type ListIterateeCustom<T, TResult> = ListIterator<T, TResult> | IterateeShorthand<T>;
type ListIteratorTypeGuard<T, S extends T> = (value: T, index: number, collection: List<T>) => value is S;
// Note: key should be string, not keyof T, because the actual object may contain extra properties that were not specified in the type.
type ObjectIterator<TObject, TResult> = (value: TObject[keyof TObject], key: string, collection: TObject) => TResult;
type ObjectIteratee<TObject> = ObjectIterator<TObject, NotVoid> | IterateeShorthand<TObject[keyof TObject]>;
type ObjectIterateeCustom<TObject, TResult> = ObjectIterator<TObject, TResult> | IterateeShorthand<TObject[keyof TObject]>;
type ObjectIteratorTypeGuard<TObject, S extends TObject[keyof TObject]> = (value: TObject[keyof TObject], key: string, collection: TObject) => value is S;
type StringIterator<TResult> = (char: string, index: number, string: string) => TResult;
/** @deprecated Use MemoVoidArrayIterator or MemoVoidDictionaryIterator instead. */
type MemoVoidIterator<T, TResult> = (prev: TResult, curr: T, indexOrKey: any, list: T[]) => void;
/** @deprecated Use MemoListIterator or MemoObjectIterator instead. */
type MemoIterator<T, TResult> = (prev: TResult, curr: T, indexOrKey: any, list: T[]) => TResult;
type MemoListIterator<T, TResult, TList> = (prev: TResult, curr: T, index: number, list: TList) => TResult;
type MemoObjectIterator<T, TResult, TList> = (prev: TResult, curr: T, key: string, list: TList) => TResult;
type MemoIteratorCapped<T, TResult> = (prev: TResult, curr: T) => TResult;
type MemoIteratorCappedRight<T, TResult> = (curr: T, prev: TResult) => TResult;
type MemoVoidArrayIterator<T, TResult> = (acc: TResult, curr: T, index: number, arr: T[]) => void;
type MemoVoidDictionaryIterator<T, K extends string | number | symbol, TResult> = (acc: TResult, curr: T, key: K, dict: Record<K, T>) => void;
type MemoVoidIteratorCapped<T, TResult> = (acc: TResult, curr: T) => void;
type ValueIteratee<T> = ((value: T) => NotVoid) | IterateeShorthand<T>;
type ValueIterateeCustom<T, TResult> = ((value: T) => TResult) | IterateeShorthand<T>;
type ValueIteratorTypeGuard<T, S extends T> = (value: T) => value is S;
type ValueKeyIteratee<T> = ((value: T, key: string) => NotVoid) | IterateeShorthand<T>;
type ValueKeyIterateeTypeGuard<T, S extends T> = (value: T, key: string) => value is S;
type Comparator<T> = (a: T, b: T) => boolean;
type Comparator2<T1, T2> = (a: T1, b: T2) => boolean;
type PropertyName = string | number | symbol;
type PropertyPath = Many<PropertyName>;
/** Common interface between Arrays and jQuery objects */
type List<T> = ArrayLike<T>;
interface Dictionary<T> {
[index: string]: T;
}
interface NumericDictionary<T> {
[index: number]: T;
}
// Crazy typedef needed get _.omit to work properly with Dictionary and NumericDictionary
type AnyKindOfDictionary =
| Dictionary<unknown>
| NumericDictionary<unknown>;
type PartialShallow<T> = {
[P in keyof T]?: T[P] extends object ? object : T[P]
};
// For backwards compatibility
type LoDashImplicitArrayWrapper<T> = LoDashImplicitWrapper<T[]>;
type LoDashImplicitNillableArrayWrapper<T> = LoDashImplicitWrapper<T[] | null | undefined>;
type LoDashImplicitObjectWrapper<T> = LoDashImplicitWrapper<T>;
type LoDashImplicitNillableObjectWrapper<T> = LoDashImplicitWrapper<T | null | undefined>;
type LoDashImplicitNumberArrayWrapper = LoDashImplicitWrapper<number[]>;
type LoDashImplicitStringWrapper = LoDashImplicitWrapper<string>;
type LoDashExplicitArrayWrapper<T> = LoDashExplicitWrapper<T[]>;
type LoDashExplicitNillableArrayWrapper<T> = LoDashExplicitWrapper<T[] | null | undefined>;
type LoDashExplicitObjectWrapper<T> = LoDashExplicitWrapper<T>;
type LoDashExplicitNillableObjectWrapper<T> = LoDashExplicitWrapper<T | null | undefined>;
type LoDashExplicitNumberArrayWrapper = LoDashExplicitWrapper<number[]>;
type LoDashExplicitStringWrapper = LoDashExplicitWrapper<string>;
type DictionaryIterator<T, TResult> = ObjectIterator<Dictionary<T>, TResult>;
type DictionaryIteratee<T> = ObjectIteratee<Dictionary<T>>;
type DictionaryIteratorTypeGuard<T, S extends T> = ObjectIteratorTypeGuard<Dictionary<T>, S>;
// NOTE: keys of objects at run time are always strings, even when a NumericDictionary is being iterated.
type NumericDictionaryIterator<T, TResult> = (value: T, key: string, collection: NumericDictionary<T>) => TResult;
type NumericDictionaryIteratee<T> = NumericDictionaryIterator<T, NotVoid> | IterateeShorthand<T>;
type NumericDictionaryIterateeCustom<T, TResult> = NumericDictionaryIterator<T, TResult> | IterateeShorthand<T>;
}

View File

@ -0,0 +1,23 @@
import _ = require("../index");
declare module "../index" {
interface LoDashStatic {
/*
* Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @return The number of milliseconds.
*/
now(): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.now
*/
now(): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.now
*/
now(): PrimitiveChain<number>;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,405 @@
import _ = require("../index");
declare module "../index" {
interface LoDashStatic {
/**
* Adds two numbers.
*
* @param augend The first number to add.
* @param addend The second number to add.
* @return Returns the sum.
*/
add(augend: number, addend: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.add
*/
add(addend: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.add
*/
add(addend: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Calculates n rounded up to precision.
*
* @param n The number to round up.
* @param precision The precision to round up to.
* @return Returns the rounded up number.
*/
ceil(n: number, precision?: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.ceil
*/
ceil(precision?: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.ceil
*/
ceil(precision?: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Divide two numbers.
*
* @param dividend The first number in a division.
* @param divisor The second number in a division.
* @returns Returns the quotient.
*/
divide(dividend: number, divisor: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.divide
*/
divide(divisor: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.divide
*/
divide(divisor: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Calculates n rounded down to precision.
*
* @param n The number to round down.
* @param precision The precision to round down to.
* @return Returns the rounded down number.
*/
floor(n: number, precision?: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.floor
*/
floor(precision?: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.floor
*/
floor(precision?: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Computes the maximum value of `array`. If `array` is empty or falsey
* `undefined` is returned.
*
* @category Math
* @param array The array to iterate over.
* @returns Returns the maximum value.
*/
max<T>(collection: List<T> | null | undefined): T | undefined;
}
interface Collection<T> {
/**
* @see _.max
*/
max(): T | undefined;
}
interface CollectionChain<T> {
/**
* @see _.max
*/
max(): ExpChain<T | undefined>;
}
interface LoDashStatic {
/**
* This method is like `_.max` except that it accepts `iteratee` which is
* invoked for each element in `array` to generate the criterion by which
* the value is ranked. The iteratee is invoked with one argument: (value).
*
* @category Math
* @param array The array to iterate over.
* @param iteratee The iteratee invoked per element.
* @returns Returns the maximum value.
* @example
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
* _.maxBy(objects, function(o) { return o.a; });
* // => { 'n': 2 }
*
* // using the `_.property` iteratee shorthand
* _.maxBy(objects, 'n');
* // => { 'n': 2 }
*/
maxBy<T>(collection: List<T> | null | undefined, iteratee?: ValueIteratee<T>): T | undefined;
}
interface Collection<T> {
/**
* @see _.maxBy
*/
maxBy(iteratee?: ValueIteratee<T>): T | undefined;
}
interface CollectionChain<T> {
/**
* @see _.maxBy
*/
maxBy(iteratee?: ValueIteratee<T>): ExpChain<T | undefined>;
}
interface LoDashStatic {
/**
* Computes the mean of the values in `array`.
*
* @category Math
* @param array The array to iterate over.
* @returns Returns the mean.
* @example
*
* _.mean([4, 2, 8, 6]);
* // => 5
*/
mean(collection: List<any> | null | undefined): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.mean
*/
mean(): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.mean
*/
mean(): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Computes the mean of the provided properties of the objects in the `array`
*
* @category Math
* @param array The array to iterate over.
* @param iteratee The iteratee invoked per element.
* @returns Returns the mean.
* @example
*
* _.mean([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], 'n');
* // => 5
*/
meanBy<T>(collection: List<T> | null | undefined, iteratee?: ValueIteratee<T>): number;
}
interface Collection<T> {
/**
* @see _.meanBy
*/
meanBy(iteratee?: ValueIteratee<T>): number;
}
interface CollectionChain<T> {
/**
* @see _.meanBy
*/
meanBy(iteratee?: ValueIteratee<T>): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Computes the minimum value of `array`. If `array` is empty or falsey
* `undefined` is returned.
*
* @category Math
* @param array The array to iterate over.
* @returns Returns the minimum value.
*/
min<T>(collection: List<T> | null | undefined): T | undefined;
}
interface Collection<T> {
/**
* @see _.min
*/
min(): T | undefined;
}
interface CollectionChain<T> {
/**
* @see _.min
*/
min(): ExpChain<T | undefined>;
}
interface LoDashStatic {
/**
* This method is like `_.min` except that it accepts `iteratee` which is
* invoked for each element in `array` to generate the criterion by which
* the value is ranked. The iteratee is invoked with one argument: (value).
*
* @category Math
* @param array The array to iterate over.
* @param iteratee The iteratee invoked per element.
* @returns Returns the minimum value.
* @example
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
* _.minBy(objects, function(o) { return o.a; });
* // => { 'n': 1 }
*
* // using the `_.property` iteratee shorthand
* _.minBy(objects, 'n');
* // => { 'n': 1 }
*/
minBy<T>(collection: List<T> | null | undefined, iteratee?: ValueIteratee<T>): T | undefined;
}
interface Collection<T> {
/**
* @see _.minBy
*/
minBy(iteratee?: ValueIteratee<T>): T | undefined;
}
interface CollectionChain<T> {
/**
* @see _.minBy
*/
minBy(iteratee?: ValueIteratee<T>): ExpChain<T | undefined>;
}
interface LoDashStatic {
/**
* Multiply two numbers.
* @param multiplier The first number in a multiplication.
* @param multiplicand The second number in a multiplication.
* @returns Returns the product.
*/
multiply(multiplier: number, multiplicand: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.multiply
*/
multiply(multiplicand: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.multiply
*/
multiply(multiplicand: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Calculates n rounded to precision.
*
* @param n The number to round.
* @param precision The precision to round to.
* @return Returns the rounded number.
*/
round(n: number, precision?: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.round
*/
round(precision?: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.round
*/
round(precision?: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Subtract two numbers.
*
* @category Math
* @param minuend The first number in a subtraction.
* @param subtrahend The second number in a subtraction.
* @returns Returns the difference.
* @example
*
* _.subtract(6, 4);
* // => 2
*/
subtract(minuend: number, subtrahend: number): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.subtract
*/
subtract(subtrahend: number): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.subtract
*/
subtract(subtrahend: number): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* Computes the sum of the values in `array`.
*
* @category Math
* @param array The array to iterate over.
* @returns Returns the sum.
* @example
*
* _.sum([4, 2, 8, 6]);
* // => 20
*/
sum(collection: List<any> | null | undefined): number;
}
interface LoDashImplicitWrapper<TValue> {
/**
* @see _.sum
*/
sum(): number;
}
interface LoDashExplicitWrapper<TValue> {
/**
* @see _.sum
*/
sum(): PrimitiveChain<number>;
}
interface LoDashStatic {
/**
* This method is like `_.sum` except that it accepts `iteratee` which is
* invoked for each element in `array` to generate the value to be summed.
* The iteratee is invoked with one argument: (value).
*
* @category Math
* @param array The array to iterate over.
* @param [iteratee=_.identity] The iteratee invoked per element.
* @returns Returns the sum.
* @example
*
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
*
* _.sumBy(objects, function(o) { return o.n; });
* // => 20
*
* // using the `_.property` iteratee shorthand
* _.sumBy(objects, 'n');
* // => 20
*/
sumBy<T>(collection: List<T> | null | undefined, iteratee?: ((value: T) => number) | string): number;
}
interface Collection<T> {
/**
* @see _.sumBy
*/
sumBy(iteratee?: ((value: T) => number) | string): number;
}
interface CollectionChain<T> {
/**
* @see _.sumBy
*/
sumBy(iteratee?: ((value: T) => number) | string): PrimitiveChain<number>;
}
}

Some files were not shown because too many files have changed in this diff Show More