@cypress/vite-dev-server 2.2.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,48 @@
1
+ # [@cypress/vite-dev-server-v3.0.0](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.2.3...@cypress/vite-dev-server-v3.0.0) (2022-06-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * issue with compilation failures in component testing ([#21599](https://github.com/cypress-io/cypress/issues/21599)) ([f2bce02](https://github.com/cypress-io/cypress/commit/f2bce02f5dcab7a73a2a1b8e102518d706a29c25))
7
+ * restart dev-server on config change ([#21212](https://github.com/cypress-io/cypress/issues/21212)) ([00a0f5a](https://github.com/cypress-io/cypress/commit/00a0f5a0e905fdfe5ef9f8ba71f915ed20ca4b72))
8
+ * sanitize internal vite plugins ([#22055](https://github.com/cypress-io/cypress/issues/22055)) ([3b5a245](https://github.com/cypress-io/cypress/commit/3b5a245ec4aa9bf9f348fbc4bc2f0decc7c4a692))
9
+ * supportFile path and supportFile false for vite on windows ([#21156](https://github.com/cypress-io/cypress/issues/21156)) ([dd180c8](https://github.com/cypress-io/cypress/commit/dd180c89b27546b0c96cc3f4fb4e75d983c8003e))
10
+ * UNIFY-1774 error if component config is not sourced for webpack/vite ([#21563](https://github.com/cypress-io/cypress/issues/21563)) ([566a7b1](https://github.com/cypress-io/cypress/commit/566a7b1feb0fc1a8f1ccf83a23d8ad7a94409a6b))
11
+ * update scaffold template to use correct path ([#20047](https://github.com/cypress-io/cypress/issues/20047)) ([6e80359](https://github.com/cypress-io/cypress/commit/6e803597a379222cf936e5977c8314d693ee1912))
12
+ * use resolved port for vite ([#21490](https://github.com/cypress-io/cypress/issues/21490)) ([630e422](https://github.com/cypress-io/cypress/commit/630e4220ca5ebbaa8c39044b86d434510b3a0f1b))
13
+ * wire up scaffolded indexHtml to dev servers ([#20453](https://github.com/cypress-io/cypress/issues/20453)) ([3a8797e](https://github.com/cypress-io/cypress/commit/3a8797e54db9fd0ef93a14ddc71c138ba8251e53))
14
+
15
+
16
+ ### chore
17
+
18
+ * prep npm packages for use with Cypress v10 ([b924d08](https://github.com/cypress-io/cypress/commit/b924d086ee2e2ccc93303731e001b2c9e9d0af17))
19
+
20
+
21
+ ### Features
22
+
23
+ * add devServer to config file ([#18962](https://github.com/cypress-io/cypress/issues/18962)) ([2573375](https://github.com/cypress-io/cypress/commit/2573375b5b6616efd2d213a94cd55fd8e0385864))
24
+ * Add typings for new devServer config ([#18797](https://github.com/cypress-io/cypress/issues/18797)) ([e018a14](https://github.com/cypress-io/cypress/commit/e018a14c211bfcbdc4568a9a737f14f5c1686e35))
25
+ * Deprecate run-ct / open-ct, and update all examples to use --ct instead ([#18422](https://github.com/cypress-io/cypress/issues/18422)) ([196e8f6](https://github.com/cypress-io/cypress/commit/196e8f62cc6d27974f235945cb5700624b3dae41))
26
+ * improved DX and support for running component and e2e tests w/ gulp ([#18135](https://github.com/cypress-io/cypress/issues/18135)) ([d39b169](https://github.com/cypress-io/cypress/commit/d39b1694aac19fdcf557236ac421e2cc1c45da8b))
27
+ * index.html configurability and storybook support ([#18242](https://github.com/cypress-io/cypress/issues/18242)) ([745b3ac](https://github.com/cypress-io/cypress/commit/745b3ac4518302983522daedf817623334feae5b))
28
+ * merging / delegating remote queries to cloud schema ([#17875](https://github.com/cypress-io/cypress/issues/17875)) ([94541d4](https://github.com/cypress-io/cypress/commit/94541d4f18591e8fa4b8702c39e92b0a7238aa5d))
29
+ * remove testFiles reference ([#20565](https://github.com/cypress-io/cypress/issues/20565)) ([5670344](https://github.com/cypress-io/cypress/commit/567034459089d9d53dfab5556cb9369fb335c3db))
30
+ * Set up cypress in cypress ([#19602](https://github.com/cypress-io/cypress/issues/19602)) ([ed51bcb](https://github.com/cypress-io/cypress/commit/ed51bcbdda480f90bef557f06c297098f1897499))
31
+ * Structuring context & schema so it can be used on the client ([#17489](https://github.com/cypress-io/cypress/issues/17489)) ([e2f395e](https://github.com/cypress-io/cypress/commit/e2f395e330f384993ed1116469102a5315a21270)), closes [#17551](https://github.com/cypress-io/cypress/issues/17551)
32
+ * support specPattern, deprecate integrationFolder and componentFolder ([#19319](https://github.com/cypress-io/cypress/issues/19319)) ([792980a](https://github.com/cypress-io/cypress/commit/792980ac12746ef47b9c944ebe4c6c353a187ab2))
33
+ * swap the #__cy_root id selector to become data-cy-root for component mounting ([#20951](https://github.com/cypress-io/cypress/issues/20951)) ([0e7b555](https://github.com/cypress-io/cypress/commit/0e7b555f93fb403f431c5de4a07ae7ad6ac89ba2))
34
+ * Use .config files ([#18578](https://github.com/cypress-io/cypress/issues/18578)) ([081dd19](https://github.com/cypress-io/cypress/commit/081dd19cc6da3da229a7af9c84f62730c85a5cd6))
35
+ * use devServer instad of startDevServer ([#20092](https://github.com/cypress-io/cypress/issues/20092)) ([8a6768f](https://github.com/cypress-io/cypress/commit/8a6768fee6f46b908c5a9daf23da8b804a6c627f))
36
+ * Use plugins on config files ([#18798](https://github.com/cypress-io/cypress/issues/18798)) ([bb8251b](https://github.com/cypress-io/cypress/commit/bb8251b752ac44f1184f9160194cf12d41fc867f))
37
+ * use supportFile by testingType ([#19364](https://github.com/cypress-io/cypress/issues/19364)) ([0366d4f](https://github.com/cypress-io/cypress/commit/0366d4fa8971e5e5189c6fd6450cc3c8d72dcfe1))
38
+ * vue-cli and nuxt preset for CT object API architecture ([#20956](https://github.com/cypress-io/cypress/issues/20956)) ([57659c4](https://github.com/cypress-io/cypress/commit/57659c42468591265143aae2ff06bae4e440085f))
39
+ * **unify:** removing prism and adding infrastructure for shiki ([#18514](https://github.com/cypress-io/cypress/issues/18514)) ([9a2e550](https://github.com/cypress-io/cypress/commit/9a2e55071d5b6dcfd97ff750b80548b834b94d30))
40
+
41
+
42
+ ### BREAKING CHANGES
43
+
44
+ * new version of packages for Cypress v10
45
+
1
46
  # [@cypress/vite-dev-server-v2.2.3](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.2.2...@cypress/vite-dev-server-v2.2.3) (2022-05-10)
2
47
 
3
48
 
package/README.md CHANGED
@@ -1,63 +1,51 @@
1
1
  # @cypress/vite-dev-server
2
2
 
3
- > ⚡️ + 🌲 Cypress Component Testing w/ Vite
4
-
5
- To install vite in you component testing environment,
6
- 1. Install it `yarn add @cypress/vite-dev-server`
7
- 2. Add it to `cypress/plugins/index.js`
8
-
9
- ```js
10
- import { startDevServer } from '@cypress/vite-dev-server'
11
-
12
- module.exports = (on, config) => {
13
- on('dev-server:start', async (options) => startDevServer({ options }))
14
-
15
- return config
16
- }
3
+ Implements the APIs for the object-syntax of the Cypress Component-testing "vite dev server".
4
+
5
+ Object syntax:
6
+
7
+ ```ts
8
+ import { defineConfig } from 'cypress'
9
+
10
+ export default defineConfig({
11
+ component: {
12
+ devServer: {
13
+ framework: 'create-react-app',
14
+ bundler: 'vite',
15
+ // viteConfig?: Will try to infer, if passed it will be used as is
16
+ }
17
+ }
18
+ })
17
19
  ```
18
20
 
19
- # @cypress/webpack-dev-server
20
-
21
- > **Note** this package is not meant to be used outside of cypress component testing.
22
-
23
- Install `@cypress/vue` or `@cypress/react` to get this package working properly
21
+ Function syntax:
22
+
23
+ ```ts
24
+ import { devServer } from '@cypress/vite-dev-server'
25
+ import { defineConfig } from 'cypress'
26
+
27
+ export default defineConfig({
28
+ component: {
29
+ devServer(cypressConfig) {
30
+ return devServer({
31
+ cypressConfig,
32
+ framework: 'react',
33
+ viteConfig: require('./vite.config.js')
34
+ })
35
+ }
36
+ }
37
+ })
38
+ ```
24
39
 
25
40
  ## Architecture
26
41
 
27
- ### Cypress server
28
-
29
- - Every HTTP request goes to the cypress server which returns an html page. We call "TOP" because of its name in the dev tools
30
- This page
31
- - renders the list of spec files
32
- - And the timetraveling command log
33
- - Finally, it renders an AUT Iframe. this iframe calls a url that has 2 parts concatenated.
34
- - a prefix: `__cypress/iframes/`
35
- - the path to the current. For example: `src/components/button.spec.tsx`
36
- - In the cypress server, calls prefixed with `__cypress/iframes/...` will be passed to the dev-server as `__cypress/src/index.html`
37
- - Every call with the prefix `__cypress/src/` will be passed to the dev-server to deal as is, without changes.
38
-
39
- ### Dev-server
40
-
41
- - Responds to every query with the prefix `__cypress/src/` (base path should be this prefix).
42
- - Responds to `__cypress/src/index.html` with an html page.
43
- This page
44
- - will contain an element `<div id="__cy_root"></div>`. Tis will be used by mount function to mount the app containing the components we want.
45
- - will load support files
46
- - will load the current spec from the url
47
- - will start the test when both files are done loading
48
- - The server re-runs the tests as soon as the current spec or any dependency is updated by calling an event `devServerEvents.emit('dev-server:compile:success')`
42
+ There should be a single publicly-exported entrypoint for the module, `devServer`, all other types and functions should be considered internal/implementation details, and types stripped from the output.
49
43
 
50
- ## Vite dev server
44
+ The `devServer` will first source the modules from the user's project, falling back to our own bundled versions of libraries. This ensures that the user has installed the current modules, and throws an error if the user does not have the library installed.
51
45
 
52
- - Takes the users `vite.config` and adds base of `__cypress/src/` and a cypress vite plugin.
53
- - The cypress plugin takes care of
54
- - responding to the index.html query with an html page
55
- - restarting the tests when files are changed
56
- - The HTML page calls a script that loads support file and the specs using a native `import()` function
57
- - Then triggers the loaded tests
46
+ From there, we check the "framework" field to source or define any known vite transforms to aid in the compilation.
58
47
 
59
- Vite is responsible for compiling and bundling all the files. We use its error overlay to display any transpiling error.
60
- Only runtime errors have to be handled through cypress
48
+ We then merge the sourced config with the user's vite config, and layer on our own transforms, and provide this to a vite instance. The vite instance used to create a vite-dev-server, which is returned.
61
49
 
62
50
  ## Changelog
63
51
 
@@ -1,18 +1,35 @@
1
1
  // This file is merged in a <script type=module> into index.html
2
2
  // it will be used to load and kick start the selected spec
3
- import specLoaders from 'cypress:spec-loaders'
4
- import { hasSupportPath, originAutUrl } from 'cypress:config'
5
3
 
6
- const specPath = window.location.pathname.replace(originAutUrl, '')
4
+ const CypressInstance = window.Cypress = parent.Cypress
5
+
6
+ const importsToLoad = []
7
+
8
+ /* Support file import logic, this should be removed once we
9
+ * are able to return relative paths from the supportFile
10
+ * Jira #UNIFY-1260
11
+ */
12
+ const supportFile = CypressInstance.config('supportFile')
13
+ const projectRoot = CypressInstance.config('projectRoot')
14
+ const devServerPublicPathRoute = CypressInstance.config('devServerPublicPathRoute')
15
+
16
+ if (supportFile) {
17
+ let supportRelativeToProjectRoot = supportFile.replace(projectRoot, '')
7
18
 
8
- const specLoader = specLoaders[specPath]
9
- const importsToLoad = [specLoader || (() => import(/* @vite-ignore */ specPath))]
19
+ if (CypressInstance.config('platform') === 'win32') {
20
+ const platformProjectRoot = projectRoot.replaceAll('/', '\\')
10
21
 
11
- if (hasSupportPath) {
12
- importsToLoad.unshift(() => import('cypress:support-path'))
22
+ supportRelativeToProjectRoot = supportFile.replace(platformProjectRoot, '')
23
+ }
24
+
25
+ // We need a slash before /cypress/supportFile.js, this happens by default
26
+ // with the current string replacement logic.
27
+ importsToLoad.push(() => import(`${devServerPublicPathRoute}${supportRelativeToProjectRoot}`))
13
28
  }
14
29
 
15
- const CypressInstance = window.Cypress = parent.Cypress
30
+ /* Spec file import logic */
31
+ // We need a slash before /src/my-spec.js, this does not happen by default.
32
+ importsToLoad.push(() => import(`${devServerPublicPathRoute}/${CypressInstance.spec.relative}`))
16
33
 
17
34
  if (!CypressInstance) {
18
35
  throw new Error('Tests cannot run without a reference to Cypress!')
@@ -0,0 +1 @@
1
+ export declare const configFiles: string[];
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configFiles = void 0;
4
+ exports.configFiles = [
5
+ 'vite.config.ts',
6
+ 'vite.config.js',
7
+ 'vite.config.mjs',
8
+ 'vite.config.cjs',
9
+ ];
@@ -0,0 +1,17 @@
1
+ /// <reference types="cypress" />
2
+ /// <reference types="node" />
3
+ declare const ALL_FRAMEWORKS: readonly ["react", "vue"];
4
+ export declare type ViteDevServerConfig = {
5
+ specs: Cypress.Spec[];
6
+ cypressConfig: Cypress.PluginConfigOptions;
7
+ devServerEvents: NodeJS.EventEmitter;
8
+ onConfigNotFound?: (devServer: 'vite', cwd: string, lookedIn: string[]) => void;
9
+ } & {
10
+ framework?: typeof ALL_FRAMEWORKS[number];
11
+ viteConfig?: unknown;
12
+ };
13
+ export declare function devServer(config: ViteDevServerConfig): Promise<Cypress.ResolvedDevServerConfig>;
14
+ export declare namespace devServer {
15
+ var create: (devServerConfig: ViteDevServerConfig, vite: typeof import("vite")) => Promise<import("vite").ViteDevServer>;
16
+ }
17
+ export {};
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devServer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
6
+ const getVite_1 = require("./getVite");
7
+ const resolveConfig_1 = require("./resolveConfig");
8
+ const debug = (0, debug_1.default)('cypress:vite-dev-server:devServer');
9
+ const ALL_FRAMEWORKS = ['react', 'vue'];
10
+ async function devServer(config) {
11
+ // This has to be the first thing we do as we need to source vite from their project's dependencies
12
+ const vite = (0, getVite_1.getVite)(config);
13
+ debug('Creating Vite Server');
14
+ const server = await devServer.create(config, vite);
15
+ debug('Vite server created');
16
+ await server.listen();
17
+ const { port } = server.config.server;
18
+ if (!port) {
19
+ throw new Error('Missing vite dev server port.');
20
+ }
21
+ debug('Successfully launched the vite server on port', port);
22
+ return {
23
+ port,
24
+ // Close is for unit testing only. We kill this child process which will handle the closing of the server
25
+ close(cb) {
26
+ return server.close().then(() => cb === null || cb === void 0 ? void 0 : cb()).catch(cb);
27
+ },
28
+ };
29
+ }
30
+ exports.devServer = devServer;
31
+ devServer.create = async function createDevServer(devServerConfig, vite) {
32
+ try {
33
+ const config = await (0, resolveConfig_1.createViteDevServerConfig)(devServerConfig, vite);
34
+ return await vite.createServer(config);
35
+ }
36
+ catch (err) {
37
+ if (err instanceof Error) {
38
+ throw err;
39
+ }
40
+ throw new Error(err);
41
+ }
42
+ };
@@ -0,0 +1,3 @@
1
+ import type { ViteDevServerConfig } from './devServer';
2
+ export declare type Vite = typeof import('vite');
3
+ export declare function getVite(config: ViteDevServerConfig): Vite;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVite = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
6
+ const debug = (0, debug_1.default)('cypress:vite-dev-server:getVite');
7
+ // "vite-dev-server" is bundled in the binary, so we need to require.resolve "vite"
8
+ // from root of the active project since we don't bundle vite internally but rather
9
+ // use the version the user has installed
10
+ function getVite(config) {
11
+ try {
12
+ const viteImportPath = require.resolve('vite', { paths: [config.cypressConfig.projectRoot] });
13
+ debug('resolved viteImportPath as %s', viteImportPath);
14
+ return require(viteImportPath);
15
+ }
16
+ catch (err) {
17
+ throw new Error(`Could not find "vite" in your project's dependencies. Please install "vite" to fix this error.\n\n${err}`);
18
+ }
19
+ }
20
+ exports.getVite = getVite;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,3 @@
1
- /// <reference types="cypress" />
2
- import { InlineConfig } from 'vite';
3
- import { StartDevServerOptions } from './resolveServerConfig';
4
- export { StartDevServerOptions };
5
- export declare function startDevServer(startDevServerArgs: StartDevServerOptions): Promise<Cypress.ResolvedDevServerConfig>;
6
- export declare type CypressViteDevServerConfig = Omit<InlineConfig, 'base' | 'root'>;
7
- export declare function devServer(cypressDevServerConfig: Cypress.DevServerConfig, devServerConfig?: CypressViteDevServerConfig): Promise<Cypress.ResolvedDevServerConfig>;
8
- export declare function defineDevServerConfig(devServerConfig: CypressViteDevServerConfig): CypressViteDevServerConfig;
1
+ import { devServer } from './devServer';
2
+ export { devServer };
3
+ export default devServer;
package/dist/index.js CHANGED
@@ -1,29 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defineDevServerConfig = exports.devServer = exports.startDevServer = void 0;
4
- const debug_1 = require("debug");
5
- const vite_1 = require("vite");
6
- const resolveServerConfig_1 = require("./resolveServerConfig");
7
- const debug = (0, debug_1.debug)('cypress:vite-dev-server:vite');
8
- async function startDevServer(startDevServerArgs) {
9
- if (!startDevServerArgs.viteConfig) {
10
- debug('User did not pass in any Vite dev server configuration');
11
- startDevServerArgs.viteConfig = {};
12
- }
13
- debug('starting vite dev server');
14
- const resolvedConfig = await (0, resolveServerConfig_1.resolveServerConfig)(startDevServerArgs);
15
- const port = resolvedConfig.server.port;
16
- const viteDevServer = await (0, vite_1.createServer)(resolvedConfig);
17
- await viteDevServer.listen();
18
- debug('Component testing vite server started on port', port);
19
- return { port, close: viteDevServer.close };
20
- }
21
- exports.startDevServer = startDevServer;
22
- function devServer(cypressDevServerConfig, devServerConfig) {
23
- return startDevServer({ options: cypressDevServerConfig, viteConfig: devServerConfig });
24
- }
25
- exports.devServer = devServer;
26
- function defineDevServerConfig(devServerConfig) {
27
- return devServerConfig;
28
- }
29
- exports.defineDevServerConfig = defineDevServerConfig;
3
+ exports.devServer = void 0;
4
+ const devServer_1 = require("./devServer");
5
+ Object.defineProperty(exports, "devServer", { enumerable: true, get: function () { return devServer_1.devServer; } });
6
+ exports.default = devServer_1.devServer;
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { Vite } from '../getVite';
3
+ import type { ViteDevServerConfig } from '../devServer';
4
+ export declare const Cypress: (options: ViteDevServerConfig, vite: Vite) => Plugin;
@@ -1,80 +1,66 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.makeCypressPlugin = void 0;
7
- const path_1 = require("path");
8
- const promises_1 = require("fs/promises");
9
- const debug_1 = __importDefault(require("debug"));
10
- const vite_1 = require("vite");
11
- const debug = (0, debug_1.default)('cypress:vite-dev-server:plugin');
12
- const pluginName = 'cypress-transform-html';
13
- const OSSepRE = new RegExp(`\\${path_1.sep}`, 'g');
14
- function convertPathToPosix(path) {
15
- return path_1.sep === '/'
16
- ? path
17
- : path.replace(OSSepRE, '/');
18
- }
19
- const INIT_FILEPATH = (0, path_1.resolve)(__dirname, '../client/initCypressTests.js');
3
+ exports.Cypress = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
6
+ const pathe_1 = require("pathe");
7
+ const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
8
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
9
+ const debug = (0, debug_1.default)('cypress:vite-dev-server:plugins:cypress');
10
+ const INIT_FILEPATH = (0, pathe_1.resolve)(__dirname, '../../client/initCypressTests.js');
20
11
  const HMR_DEPENDENCY_LOOKUP_MAX_ITERATION = 50;
21
12
  function getSpecsPathsSet(specs) {
22
13
  return new Set(specs.map((spec) => spec.absolute));
23
14
  }
24
- const makeCypressPlugin = (projectRoot, supportFilePath, devServerEvents, specs) => {
15
+ const Cypress = (options, vite) => {
25
16
  let base = '/';
17
+ const projectRoot = options.cypressConfig.projectRoot;
18
+ const supportFilePath = options.cypressConfig.supportFile ? path_1.default.resolve(projectRoot, options.cypressConfig.supportFile) : false;
19
+ const devServerEvents = options.devServerEvents;
20
+ const specs = options.specs;
21
+ const indexHtmlFile = options.cypressConfig.indexHtmlFile;
26
22
  let specsPathsSet = getSpecsPathsSet(specs);
23
+ let loader = fs_1.default.readFileSync(INIT_FILEPATH, 'utf8');
27
24
  devServerEvents.on('dev-server:specs:changed', (specs) => {
28
25
  specsPathsSet = getSpecsPathsSet(specs);
29
26
  });
30
- const posixSupportFilePath = supportFilePath ? convertPathToPosix((0, path_1.resolve)(projectRoot, supportFilePath)) : undefined;
31
27
  return {
32
- name: pluginName,
28
+ name: 'cypress:main',
33
29
  enforce: 'pre',
34
30
  configResolved(config) {
35
31
  base = config.base;
36
32
  },
37
33
  async transformIndexHtml() {
38
- const indexHtmlPath = (0, path_1.resolve)(__dirname, '..', 'index.html');
39
- const indexHtmlContent = await (0, promises_1.readFile)(indexHtmlPath, { encoding: 'utf8' });
34
+ const indexHtmlPath = (0, pathe_1.resolve)(projectRoot, indexHtmlFile);
35
+ debug('resolved the indexHtmlPath as', indexHtmlPath, 'from', indexHtmlFile);
36
+ const indexHtmlContent = await fs_1.default.promises.readFile(indexHtmlPath, { encoding: 'utf8' });
40
37
  // find </body> last index
41
38
  const endOfBody = indexHtmlContent.lastIndexOf('</body>');
42
39
  // insert the script in the end of the body
43
- return `${indexHtmlContent.substring(0, endOfBody)}<script src="${base}cypress:client-init-test" type="module"></script>${indexHtmlContent.substring(endOfBody)}`;
44
- },
45
- resolveId(id) {
46
- if (id === 'cypress:config') {
47
- return id;
48
- }
49
- if (id === 'cypress:support-path') {
50
- return posixSupportFilePath;
51
- }
52
- if (id === 'cypress:spec-loaders') {
53
- return id;
54
- }
55
- if (id === '/cypress:client-init-test') {
56
- return INIT_FILEPATH;
57
- }
58
- },
59
- load(id) {
60
- if (id === 'cypress:spec-loaders') {
61
- return `export default {\n${specs.map((s) => {
62
- return `${JSON.stringify(encodeURI(s.relative))}:()=>import(${JSON.stringify(s.absolute)})`;
63
- }).join(',\n')}\n}`;
64
- }
65
- if (id === 'cypress:config') {
66
- return `
67
- export const hasSupportPath = ${JSON.stringify(!!supportFilePath)}
68
- export const originAutUrl = ${JSON.stringify(`/__cypress/iframes/${(0, vite_1.normalizePath)(projectRoot)}/`)}`;
69
- }
40
+ return `${indexHtmlContent.substring(0, endOfBody)}<script>
41
+ ${loader}
42
+ </script>${indexHtmlContent.substring(endOfBody)}`;
70
43
  },
71
44
  configureServer: async (server) => {
72
- const indexHtml = await (0, promises_1.readFile)((0, path_1.resolve)(__dirname, '..', 'index.html'), { encoding: 'utf8' });
73
- const transformedIndexHtml = await server.transformIndexHtml(base, indexHtml);
74
- server.middlewares.use(`${base}index.html`, (req, res) => res.end(transformedIndexHtml));
45
+ server.middlewares.use(`${base}index.html`, async (req, res) => {
46
+ let transformedIndexHtml = await server.transformIndexHtml(base, '');
47
+ const viteImport = `<script type="module" src="${options.cypressConfig.devServerPublicPathRoute}/@vite/client"></script>`;
48
+ // If we're doing cy-in-cy, we need to be able to access the Cypress instance from the parent frame.
49
+ if (process.env.CYPRESS_INTERNAL_VITE_OPEN_MODE_TESTING) {
50
+ transformedIndexHtml = transformedIndexHtml.replace(viteImport, `<script>document.domain = 'localhost';</script>${viteImport}`);
51
+ }
52
+ return res.end(transformedIndexHtml);
53
+ });
75
54
  },
76
55
  handleHotUpdate: ({ server, file }) => {
77
56
  debug('handleHotUpdate - file', file);
57
+ // If the user provided IndexHtml is changed, do a full-reload
58
+ if (vite.normalizePath(file) === (0, pathe_1.resolve)(projectRoot, indexHtmlFile)) {
59
+ server.ws.send({
60
+ type: 'full-reload',
61
+ });
62
+ return;
63
+ }
78
64
  // get the graph node for the file that just got updated
79
65
  let moduleImporters = server.moduleGraph.fileToModulesMap.get(file);
80
66
  let iterationNumber = 0;
@@ -92,7 +78,7 @@ export const originAutUrl = ${JSON.stringify(`/__cypress/iframes/${(0, vite_1.no
92
78
  debug('handleHotUpdate - support compile success');
93
79
  devServerEvents.emit('dev-server:compile:success');
94
80
  // if we update support we know we have to re-run it all
95
- // no need to ckeck further
81
+ // no need to check further
96
82
  return [];
97
83
  }
98
84
  if (mod.file && specsPathsSet.has(mod.file)) {
@@ -111,7 +97,7 @@ export const originAutUrl = ${JSON.stringify(`/__cypress/iframes/${(0, vite_1.no
111
97
  },
112
98
  };
113
99
  };
114
- exports.makeCypressPlugin = makeCypressPlugin;
100
+ exports.Cypress = Cypress;
115
101
  /**
116
102
  * Gets all the modules that import the set of modules passed in parameters
117
103
  * @param modules the set of module whose dependents to return
@@ -0,0 +1,2 @@
1
+ export * from './inspect';
2
+ export * from './cypress';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ (0, tslib_1.__exportStar)(require("./inspect"), exports);
5
+ (0, tslib_1.__exportStar)(require("./cypress"), exports);
@@ -0,0 +1,3 @@
1
+ import type { PluginOption } from 'vite';
2
+ import type { ViteDevServerConfig } from '../devServer';
3
+ export declare const CypressInspect: (config: ViteDevServerConfig) => PluginOption | null;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CypressInspect = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
6
+ const debug = (0, debug_1.default)('cypress:vite-dev-server:plugins:inspect');
7
+ const CypressInspect = (config) => {
8
+ var _a;
9
+ if (!process.env.CYPRESS_INTERNAL_VITE_INSPECT) {
10
+ debug('skipping vite inspect because CYPRESS_INTERNAL_VITE_INSPECT is not set');
11
+ return null;
12
+ }
13
+ let Inspect;
14
+ try {
15
+ const inspectPluginPath = require.resolve('vite-plugin-inspect', { paths: [config.cypressConfig.projectRoot] });
16
+ const inspectModule = require(inspectPluginPath);
17
+ Inspect = (_a = inspectModule.default) !== null && _a !== void 0 ? _a : inspectModule;
18
+ debug('inspect was found', Inspect);
19
+ }
20
+ catch (err) {
21
+ debug(`Tried to import the inspect plugin 'vite-plugin-inspect'. It's an optional peerDependency so install it if you'd like.`);
22
+ debug(err);
23
+ return null;
24
+ }
25
+ return Object.assign(Object.assign({}, Inspect()), { name: 'cypress:inspect' });
26
+ };
27
+ exports.CypressInspect = CypressInspect;
@@ -0,0 +1,3 @@
1
+ import type { ViteDevServerConfig } from './devServer';
2
+ import type { Vite } from './getVite';
3
+ export declare const createViteDevServerConfig: (config: ViteDevServerConfig, vite: Vite) => Promise<Record<string, any>>;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createViteDevServerConfig = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /**
6
+ * The logic inside of this file is heavily reused from
7
+ * Vitest's own config resolution logic.
8
+ * You can find it here https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/create.ts
9
+ */
10
+ const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
11
+ const local_pkg_1 = require("local-pkg");
12
+ const pathe_1 = require("pathe");
13
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
14
+ const constants_1 = require("./constants");
15
+ const index_1 = require("./plugins/index");
16
+ const debug = (0, debug_1.default)('cypress:vite-dev-server:resolve-config');
17
+ const createViteDevServerConfig = async (config, vite) => {
18
+ const { specs, cypressConfig, viteConfig: viteOverrides } = config;
19
+ const root = cypressConfig.projectRoot;
20
+ const { default: findUp } = await (0, local_pkg_1.importModule)('find-up');
21
+ const configFile = await findUp(constants_1.configFiles, { cwd: root });
22
+ // INFO logging, a lot is logged here.
23
+ // debug('all dev-server options are', options)
24
+ if (configFile) {
25
+ debug('resolved config file at', configFile, 'using root', root);
26
+ }
27
+ else if (viteOverrides) {
28
+ debug(`Couldn't find a Vite config file, however we received a custom viteConfig`, viteOverrides);
29
+ }
30
+ else {
31
+ if (config.onConfigNotFound) {
32
+ config.onConfigNotFound('vite', root, constants_1.configFiles);
33
+ // The config process will be killed from the parent, but we want to early exit so we don't get
34
+ // any additional errors related to not having a config
35
+ process.exit(0);
36
+ }
37
+ else {
38
+ throw new Error(`Your component devServer config for vite is missing a required viteConfig property, since we could not automatically detect one.\n Please add one to your ${config.cypressConfig.configFile}`);
39
+ }
40
+ }
41
+ // Vite caches its output in the .vite directory in the node_modules where vite lives.
42
+ // So we want to find that node_modules path and ensure it's added to the "allow" list
43
+ const vitePathNodeModules = path_1.default.dirname(path_1.default.dirname(require.resolve(`vite/package.json`, {
44
+ paths: [root],
45
+ })));
46
+ const viteBaseConfig = {
47
+ root,
48
+ base: `${cypressConfig.devServerPublicPathRoute}/`,
49
+ configFile,
50
+ optimizeDeps: {
51
+ esbuildOptions: {
52
+ incremental: true,
53
+ plugins: [
54
+ {
55
+ name: 'cypress-esbuild-plugin',
56
+ setup(build) {
57
+ build.onEnd(function (result) {
58
+ // We don't want to completely fail the build here on errors so we treat the errors as warnings
59
+ // which will handle things more gracefully. Vite will 500 on files that have errors when they
60
+ // are requested later and Cypress will display an error message.
61
+ // See: https://github.com/cypress-io/cypress/pull/21599
62
+ result.warnings = [...result.warnings, ...result.errors];
63
+ result.errors = [];
64
+ });
65
+ },
66
+ },
67
+ ],
68
+ },
69
+ entries: [
70
+ ...specs.map((s) => (0, pathe_1.relative)(root, s.relative)),
71
+ ...(cypressConfig.supportFile ? [(0, pathe_1.resolve)(root, cypressConfig.supportFile)] : []),
72
+ ].filter((v) => v != null),
73
+ },
74
+ server: {
75
+ fs: {
76
+ allow: [
77
+ root,
78
+ vitePathNodeModules,
79
+ cypressConfig.cypressBinaryRoot,
80
+ ],
81
+ },
82
+ },
83
+ plugins: [
84
+ (0, index_1.Cypress)(config, vite),
85
+ (0, index_1.CypressInspect)(config),
86
+ ].filter((p) => p != null),
87
+ };
88
+ const finalConfig = vite.mergeConfig(viteBaseConfig, viteOverrides);
89
+ debug('The resolved server config is', JSON.stringify(finalConfig, null, 2));
90
+ return finalConfig;
91
+ };
92
+ exports.createViteDevServerConfig = createViteDevServerConfig;
package/package.json CHANGED
@@ -1,36 +1,33 @@
1
1
  {
2
2
  "name": "@cypress/vite-dev-server",
3
- "version": "2.2.3",
3
+ "version": "3.0.0",
4
4
  "description": "Launches Vite Dev Server for Component Testing",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "build": "tsc",
8
- "build-prod": "tsc",
9
- "cy:open": "node ../../scripts/cypress.js open-ct --project ${PWD}",
10
- "cy:run": "node ../../scripts/cypress.js run-ct --project ${PWD}",
11
- "cy:run-signature": "yarn cy:run --config=\"{\\\"pluginsFile\\\":\\\"cypress/new-signature/plugins.js\\\"}\"",
12
- "test": "yarn cy:run && yarn cy:run-signature",
13
- "watch": "tsc -w"
7
+ "build": "tsc || echo 'built, with type errors'",
8
+ "build-prod": "tsc || echo 'built, with type errors'",
9
+ "check-ts": "tsc --noEmit",
10
+ "cypress:run": "yarn cypress:run-cypress-in-cypress node ../../scripts/cypress run --project . --browser chrome",
11
+ "cypress:run-cypress-in-cypress": "cross-env HTTP_PROXY_TARGET_FOR_ORIGIN_REQUESTS=http://localhost:4455 CYPRESS_REMOTE_DEBUGGING_PORT=6666 TZ=America/New_York",
12
+ "cypress:open": "yarn cypress:run-cypress-in-cypress gulp open --project .",
13
+ "watch": "tsc -w",
14
+ "test": "yarn test-unit",
15
+ "test-unit": "mocha -r ts-node/register/transpile-only --config ./test/.mocharc.js"
14
16
  },
15
17
  "dependencies": {
16
- "debug": "^4.3.2",
17
- "get-port": "^5.1.1"
18
+ "debug": "4.3.3",
19
+ "find-up": "6.3.0",
20
+ "local-pkg": "0.4.1",
21
+ "pathe": "0.2.0"
18
22
  },
19
23
  "devDependencies": {
20
- "@cypress/react": "0.0.0-development",
21
- "@cypress/vue": "0.0.0-development",
22
- "@testing-library/cypress": "7.0.4",
23
- "@vitejs/plugin-vue": "1.2.0",
24
- "@vue/compiler-sfc": "3.0.9",
25
- "cypress": "0.0.0-development",
26
- "mocha-junit-reporter": "^2.0.0",
27
- "mocha-multi-reporters": "^1.5.1",
28
- "react": "17.0.2",
29
- "vite": "2.2.3",
30
- "vue": "3.0.11"
31
- },
32
- "peerDependencies": {
33
- "vite": ">= 2.1.3"
24
+ "chai": "^4.3.6",
25
+ "dedent": "^0.7.0",
26
+ "mocha": "^9.2.2",
27
+ "sinon": "^13.0.1",
28
+ "ts-node": "^10.2.1",
29
+ "vite": "2.9.0-beta.3",
30
+ "vite-plugin-inspect": "0.4.3"
34
31
  },
35
32
  "files": [
36
33
  "dist",
@@ -1,9 +0,0 @@
1
- /// <reference types="node" />
2
- /// <reference types="cypress" />
3
- import { Plugin } from 'vite';
4
- interface Spec {
5
- absolute: string;
6
- relative: string;
7
- }
8
- export declare const makeCypressPlugin: (projectRoot: string, supportFilePath: string | false, devServerEvents: NodeJS.EventEmitter, specs: Spec[]) => Plugin;
9
- export {};
@@ -1,16 +0,0 @@
1
- /// <reference types="cypress" />
2
- import type { InlineConfig } from 'vite';
3
- export interface StartDevServerOptions {
4
- /**
5
- * the Cypress dev server configuration object
6
- */
7
- options: Cypress.DevServerConfig;
8
- /**
9
- * By default, vite will use your vite.config file to
10
- * Start the server. If you need additional plugins or
11
- * to override some options, you can do so using this.
12
- * @optional
13
- */
14
- viteConfig?: Omit<InlineConfig, 'base' | 'root'>;
15
- }
16
- export declare const resolveServerConfig: ({ viteConfig, options }: StartDevServerOptions) => Promise<InlineConfig>;
@@ -1,56 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.resolveServerConfig = void 0;
7
- const debug_1 = __importDefault(require("debug"));
8
- const path_1 = require("path");
9
- const get_port_1 = __importDefault(require("get-port"));
10
- const makeCypressPlugin_1 = require("./makeCypressPlugin");
11
- const debug = (0, debug_1.default)('cypress:vite-dev-server:start');
12
- const resolveServerConfig = async ({ viteConfig, options }) => {
13
- const { projectRoot, supportFile } = options.config;
14
- const requiredOptions = {
15
- base: '/__cypress/src/',
16
- root: projectRoot,
17
- };
18
- const finalConfig = { ...viteConfig, ...requiredOptions };
19
- finalConfig.plugins = [...(finalConfig.plugins || []), (0, makeCypressPlugin_1.makeCypressPlugin)(projectRoot, supportFile, options.devServerEvents, options.specs)];
20
- // This alias is necessary to avoid a "prefixIdentifiers" issue from slots mounting
21
- // only cjs compiler-core accepts using prefixIdentifiers in slots which vue test utils use.
22
- // Could we resolve this usage in test-utils?
23
- try {
24
- finalConfig.resolve = finalConfig.resolve || {};
25
- finalConfig.resolve.alias = {
26
- ...finalConfig.resolve.alias,
27
- '@vue/compiler-core': (0, path_1.resolve)((0, path_1.dirname)(require.resolve('@vue/compiler-core')), 'dist', 'compiler-core.cjs.js'),
28
- };
29
- }
30
- catch (e) {
31
- // Vue 3 is not installed
32
- }
33
- finalConfig.server = finalConfig.server || {};
34
- finalConfig.server.port = await (0, get_port_1.default)({ port: finalConfig.server.port || 3000 }),
35
- // Ask vite to pre-optimize all dependencies of the specs
36
- finalConfig.optimizeDeps = finalConfig.optimizeDeps || {};
37
- // pre-optimize all the specs
38
- if ((options.specs && options.specs.length)) {
39
- // fix: we must preserve entries configured on target project
40
- const existingOptimizeDepsEntries = finalConfig.optimizeDeps.entries;
41
- if (existingOptimizeDepsEntries) {
42
- finalConfig.optimizeDeps.entries = [...existingOptimizeDepsEntries, ...options.specs.map((spec) => spec.relative)];
43
- }
44
- else {
45
- finalConfig.optimizeDeps.entries = [...options.specs.map((spec) => spec.relative)];
46
- }
47
- // only optimize a supportFile is it is not false or undefined
48
- if (supportFile) {
49
- // fix: on windows we need to replace backslashes with slashes
50
- finalConfig.optimizeDeps.entries.push(supportFile.replace(/\\/g, '/'));
51
- }
52
- }
53
- debug(`the resolved server config is ${JSON.stringify(finalConfig, null, 2)}`);
54
- return finalConfig;
55
- };
56
- exports.resolveServerConfig = resolveServerConfig;
package/index.html DELETED
@@ -1,12 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
- <title>AUT Frame</title>
8
- </head>
9
- <body>
10
- <div id="__cy_root"></div>
11
- </body>
12
- </html>