Open Samuel-Schober-USU opened 1 year ago
VERY interested in this, as well. Seem like the lift may not be massive but the value would be tremendous for those invested in web component architecture.
Here's a simple example showing how to make a mount function for Web Components: https://github.com/lmiller1990/cypress-web-components-example
We can no doubt do something similar for Stencil!
Any news about this ?
@pedroresende Sure is, I'm working on a better way to add support for third party libraries to our onboarding workflow. You can follow that here: https://github.com/cypress-io/cypress/issues/25637
The code is almost done, I expect we can ship this before the end of Feb 2023. Then we can work on some Stencil integrations, without needing to make a PR against Cypress. There will be better documentation on how to integrate with Cypress (basically like https://github.com/lmiller1990/cypress-web-components-example, but once someone does it, everyone can re-use the integration).
I haven't used Stencil before, but it should be easy enough to integrate.
Hi @pedroresende @chris-kt @Samuel-Schober-USU, we have a public API for this feature coming in the next release.
If either of you is interested, you could either make your own one for Stencil now. If you want to work on it together or have any questions, please let me know.
Hi @pedroresende @chris-kt @Samuel-Schober-USU, we have a public API for this feature coming in the next release.
- Docs (preview): https://cypress-documentation-git-lmiller-ct-public-api-docs-cypress-io.vercel.app/guides/component-testing/third-party-definitions
- Docs PR: CT Public API docs cypress-documentation#5069
- Example implementation for Solid.js https://github.com/lmiller1990/cypress-ct-solid-js
- Template: https://github.com/cypress-io/cypress-ct-definition-template
If either of you is interested, you could either make your own one for Stencil now. If you want to work on it together or have any questions, please let me know.
Hi @lmiller1990 - I'm looking into implement this for stencil js, it is currently not mounting the component using cypress. It would be good if you have any experience here
Sure, got a repository I can contribute to or take a look at? Happy to help out, I know this still really well, would love to try writing some Stencil components and tests.
Sure, got a repository I can contribute to or take a look at? Happy to help out, I know this still really well, would love to try writing some Stencil components and tests.
Thats great! I have already started implementing, however for some reason i can't see the mounting component in the html. As shown in the screenshots
(1) `test-file.tsx'
(2) 'test-file.cy.tsx`
(3) Actual test in cypress
Hi! Can you please post a minimal repository I can clone and run? Screenshots aren't something I'm able to debug.
Hi! Can you please post a minimal repository I can clone and run? Screenshots aren't something I'm able to debug.
I managed to mount it by using your example function for mount
import { getContainerEl, setupHooks } from "@cypress/mount-utils";
function cleanup() {
const root = getContainerEl();
root.innerHTML = '';
}
export function mount(template) {
const root = getContainerEl();
root.innerHTML = template;
// adds output to the command log
return cy.wait(0, { log: false }).then(() => {
Cypress.log({
name: "mount",
message: "Mounted component",
});
});
}
setupHooks(cleanup);
It works if I do cy.mount(
, however i'm not sure if I can pass the whole
.ts` object to the mount? It looks the mount function for stencilJs cannot import the who file for the sourceCode, is that correct? If yes is there anyway we can do that?
Something like this cy.mount('<Button { ...defaultStatProps } />')
This is the code I used
import {
defineCustomElements,
} from '../../../../dist/js/tk-components/loader';
import '../../../scss/ut_asset_toolkit.scss';
import { Button} from './button';
const defaultProps: Partial<Button> = {
variant: 'destructive',
};
defineCustomElements(window);
describe('Mount button component', () => {
beforeEach(() => {
cy.mount(<Button { ...defaultProps } />)
});
});
This is the ERROR:
The following error originated from your test code, not from Cypress.
> Module parse failed: Unexpected token (10:18)
File was processed with these loaders:
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { Button} from './button';
|
> const defaultProps: Partial<Button> = {
| variant: 'destructive',
| };
^ problem is it does not know how to pass TS, normally we will grab your config (webpack/vite/whatever) but I'm not sure what the most common/default is for Stencil JS development.
Please post a minimal reproduction I can run, I'll help out. How do your normally make a Stencil JS app? Anything is possible and I will do my best to get a production ready Stencil JS adapter working but I can't piece together something based on snippets, I need a repo I can clone and tinker with.
Taking a look... I'm trying to build something but getting
import { Component, Prop, h } from '@stencil/core';
Gives
The requested module '/__cypress/src/node_modules/.vite/deps/@stencil_core.js?v=15a1a7dc' does not provide an export named 'Component'
Same issue in Node.js:
> const s =require('@stencil/core')
undefined
> s
{ h: [Function (anonymous)] }
I do not know much about how Stencil works, it looks like they don't use a standard dev-server, so we will need to make it work with Vite / webpack or write an integration for their own thing.
Same issue if you log Component
in the Stencil starter. How does this work? Is there some kind of internal preprocessing? The docs suggest Stencil is a compiler - I guess this export is a compile time thing?
Maybe we can use their dev server: https://stenciljs.com/docs/dev-server-api
I tried but no luck yet
const { defineConfig } = require('cypress');
const devServer = require('@stencil/core/dev-server');
const compiler = require('@stencil/core/compiler');
module.exports = defineConfig({
component: {
devServer: async args => {
const port = 5553;
/** @type {import("@stencil/core/internal").StencilDevServerConfig} */
const config = {
port,
root: '__cypress/src',
logRequests: false
};
const logger = console;
logger.createTimeSpan = () => {
return {
duration: 10000,
finish: () => {
return 2000
},
};
};
logger.getLevel = () => 4;
devServer.start(config);
return {
port,
};
},
},
});
How are you supposed to use the Stencil dev server?
Another alternative is to just build the prod bundle and test those. It's not really the fast feedback loop you'd want, but until we figure out how to integrate it, it's the best I can come up with. I got this working:
import { MyComponent } from '../../dist/components/my-component'
import { getContainerEl, setupHooks } from "@cypress/mount-utils";
function cleanup() {
// runs after each test
}
function mount(template, options = {}) {
for (const [tag, comp] of Object.entries(options.components ?? {})) {
customElements.define(tag, comp);
}
// get the root element to mount the component
const root = getContainerEl();
root.innerHTML = template;
// adds output to the command log
return cy.wait(0, { log: false }).then(() => {
Cypress.log({
name: "mount",
message: "Mounted component",
});
});
}
setupHooks(cleanup);
describe('ComponentName.cy.jsx', () => {
it('playground', () => {
mount(`<my-component first="Stencil" last="'Don't call me a framework' JS"></my-component>`, {
components: {
'my-component': MyComponent
}
})
})
})
To do this I had to do npm run build
and import the dist'd output. It's just a web component, so I followed my own guide: https://github.com/lmiller1990/cypress-web-components-example/tree/main
Who is the best person to talk to on the Stencil team about how to use their dev server? Maybe @JessicaSachs can point me in the right direction.
hi @lmiller1990 - working off your example, I can get stencil's dev server started, but it closes within the stencil dev server startup process...
My devServer function in cypress.config.js is
devServer: async () => {
const port = 3333;
const config = {
port,
root: './'
};
const logger = stencilNode.createNodeLogger({process});
const stencilServer = devServer.start(config, logger);
return {
port: port,
close: {
done: (await stencilServer).close(),
},
};
},
Cypress' UI flickers to the "select browser" screen for a split second, and then I get a rather cryptic stack trace:
Error at S. (:4410:60024) at Object.onceWrapper (node:events:628:26) at S.emit (node:events:513:28) at S.emit (:4410:49620) at ChildProcess. (:4410:49047) at ChildProcess.emit (node:events:513:28) at emit (node:internal/child_process:937:14) at process.processTicksAndRejections (node:internal/process/task_queues:83:21)
While debugging, it seems to me that the stencil dev-server is shutting down due to the output "Debugger attached" being sent to stderr.
In console, I get:
dev server closed:
I wonder why the Stencil dev server is dying. It's a bit of a black box - we'll need to find out how/why that isn't working. Do you have much knowledge of it? I had a quick look, but it looks like it isn't webpack or Vite based.
@lmiller1990 I've created a package that integrates Stencil with Cypress' Component Testing :) link
Neat, I will try it out!
What would you like?
Since more and more companies are using web components and StencilJS is often used for building them, it would be awesome if Cypress could support also StencilJS components in their component testing.
Why is this needed?
Our company is currently using the Puppeteer based approach for testing our web components, but since we are already testing our applications with Cypress, we would love to have it harmonized and use Cypress everywhere.
Maybe you can also have some future cooperation with the Stencil developers so they support Cypress testing as a default instead of Puppeteer.
Other
No response