Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Parcel as a dev server #17798

Open
JessicaSachs opened this issue Aug 19, 2021 Discussed in #16977 · 22 comments
Open

Using Parcel as a dev server #17798

JessicaSachs opened this issue Aug 19, 2021 Discussed in #16977 · 22 comments
Labels
CT Issue related to component testing stage: needs investigating Someone from Cypress needs to look at this type: feature New feature that does not currently exist

Comments

@JessicaSachs
Copy link
Contributor

Discussed in #16977

Originally posted by mscoobby June 17, 2021
Hello everyone,
We've started using Cypress for testing our React based application and it works great but we are using Parcel to bundle the application and it would be nice if we don't have to introduce webpack to the project. I've looked around and tried different things but could not manage to make Cypress component testing work without webpack. I would appreciate any information on the topic.

@JessicaSachs JessicaSachs added help wanted type: feature New feature that does not currently exist stage: needs investigating Someone from Cypress needs to look at this labels Aug 19, 2021
@JessicaSachs
Copy link
Contributor Author

JessicaSachs commented Aug 19, 2021

Cross-posting my own response.

Hey!

We actually have support for Vite (+ rollup) and I'd love to get support for Parcel.

Can you send me a repository with your normal development flow? I don't know how folks usually develop Parcel apps.

For component testing, we just need some sort of a dev server. Even something like a static express #server would work just fine.

Essentially, Cypress treats each spec as a standalone "page", so we need to have a harness that respects that contract and correctly returns a "compiled" file where your spec is essentially a main.js file.

In Webpack, that's particularly difficult because we need to support a lot of Webpack's proprietary bundling features... However, but for different bundlers, it's generally pretty easy to get it working.

Anyway, shoot me over an example repo and I'll take a look 👍🏻.

@khill-fbmc
Copy link

I would be willing to help test this since I want to learn cypress and currently use Parcel.

@lmiller1990 lmiller1990 added CT Issue related to component testing and removed component testing labels Aug 15, 2022
@bvandercar-vt
Copy link

seconding this request, much needed

@isitgeorge
Copy link

+1

2 similar comments
@pedily
Copy link

pedily commented Oct 4, 2022

+1

@doelgonzo
Copy link

+1

@daviesgeek
Copy link

+1, the docs are lacking in this area

@jkliptonia
Copy link

This is very much needed, Parcel is common. Is there any workaround besides introducing webpack?

@lmiller1990
Copy link
Contributor

Agreed docs are lacking: https://cypress-documentation-8cl0tm1rj-cypress-io.vercel.app/guides/component-testing/component-framework-configuration#Custom-Dev-Server

This is almost certainly possible right now, let's work on it. First step is look at ^^^^^ docs and try pointing it at your Parcel dev server and see if you can get something rendering in Cypress Component Testing.

Once that is working, I can writeup what else is needed - basically we just need to respond with the right events. Vite dev server is probably the most "simple" example of a dev server here. The events are things like this, eg dev-server:specs:changed. Parcel most likely has a hook for this, we'd just listen to it and emit the event to tell Cypress to re-run etc.

Anyone have Parcel dev experience who'd like to work on this with me?

@lmiller1990
Copy link
Contributor

I tried a bit: https://github.com/lmiller1990/parcel-cypress-plugin

I got stuck on

Screenshot 2023-02-24 at 1 03 04 pm

Cypress is asking for localhost:1234/src/App.cy.jsx to which Parcel doesn't respond. Anyone know how I can add an extra file based on a path to Parcel's dev server? I tried the outputFS but I could not get it working.

Also, any way to customize the HTML Parcel's Dev Server uses? In Vite we can do transformIndexHtml https://vitejs.dev/guide/api-plugin.html#transformindexhtml

@daviesgeek
Copy link

@lmiller1990 i wonder if creating a custom target will make this work ok. How does Cypress interact with the dev server? When it's asking for src/App.cy.jsx, what is it expecting back?

@lmiller1990
Copy link
Contributor

Hmm good question - it's an index.html with this embedded in a <script> tag:

importsToLoad.push({
load: () => import(testFileAbsolutePathRoute),
absolute: CypressInstance.spec.absolute,
relative: CypressInstance.spec.relative,
relativeUrl: testFileAbsolutePathRoute,

It's a JS blob that imports the correct spec, and some runtime code to execute the test (fairly Cypress specific, but I can handle this - once we figure out how to tell Parcel what to serve for a given URL).

@daviesgeek
Copy link

@lmiller1990 do you think it'd be sufficient to write a small script that handles taking the path sent by Cypress to send the right response back? I don't have a good picture of the entirety of what's needed to make this work, but would a solution like that be sufficient? Parcel already rewrites requests, so it'd just be a matter of writing the proper script to handle the request.

@lmiller1990
Copy link
Contributor

@daviesgeek I think so - as long as the correct index.html is served with the right <script> injected (that loads the spec from Parcel dev-server, whatever that route turns out to be) Cypress should handle the rest.

I'm not sure I have time to work on it now, but I can definitely review/look at code if you'd like to take a look at it.

@daviesgeek
Copy link

@lmiller1990 i can see what i can do; how did you get to the point of the above where cypress is actually attempting to load the parcel dev server up? It's been a little bit , but last time I tried, i don't think i got that far

@lmiller1990
Copy link
Contributor

Been a while for me but all the code I wrote should be in this repo: https://github.com/lmiller1990/parcel-cypress-plugin/

The bulk of the dev server stuff would go in https://github.com/lmiller1990/parcel-cypress-plugin/blob/main/cypress.config.js

If you need help navigating the Cypress code base, lmk, but theoretically this should all be do-able from outside - our webpack and vite dev servers are completely separate from the main code base, too.

The code lives in this repo https://github.com/cypress-io/cypress/tree/develop/npm but they are developed and deployed in isolation. If you can get the routing to work and serve the correct spec, I can wire up all the hot reload events and that kind of thing.

@lmiller1990
Copy link
Contributor

If anyone wants to work on this, good example of how to build a dev server: https://github.com/fochlac/cypress-devserver-esbuild/tree/main

@lorenzogrv
Copy link

Hi there. I'm currently setting up a project which will accomplish this.

The most tricky part is fiddling around with the NODE_OPTIONS - specifically --openssl-legacy-provider - which isn't compatible with parcel workers. Electron has some docs about it, but I'm still determining how our dev and CI environments affect this setting.

@lorenzogrv
Copy link

lorenzogrv commented May 2, 2023

I finally reached a working setup. Few things:

  • To workaround the --openssl-legacy-provider quirk, I'm using an spawned child_process to hold the parcel bundler within, which communicates with cypress' node process via the usual IPC channel means.
  • While I'm still researching how to "inject" the extra logic need on the parcel dev server, I'm using an express app to proxy/adapt the requests coming from cypress
  • I've researched vite's dev-server cypress adapter source for real code to inject the actual tests on the client side
  • The devServerEvents parameter lacks a proper documentation. It does not even detect changes on the specs

I'm still researching and evolving the solution

@lmiller1990
Copy link
Contributor

There was some minor updates to our docs recently: https://docs.cypress.io/guides/component-testing/component-framework-configuration#Custom-Dev-Server

devServerEvents definitely needs better docs. Our implementation should have some types (I think?) so if you look at vite-dev-server that should give you some hints.

I can take a look if you are really stuck, just share your GH repo.

@lorenzogrv
Copy link

lorenzogrv commented May 8, 2023

I would like to share but the setup is still experimental and currently versioned within a private monorepo at gitlab.com.

As said, "it works". Quotes because I still need to figure out how to properly detect and trigger re-runs when specs - or the code they depend upon - change. It's sub-optimal having to refresh manually, ofc 😅 . It would be awesome if you can point me to some places at vite-dev-server source where the relevant devServerEvents are handled/emitted, I could research way quicker. A link or two would suffice, I can understand and follow the code but digging through the complexity of the cypress monorepo takes time.

I expect to extract the relevant source from the private monorepo and publish on a near future, so people looking for a pattern to integrate with parcel can benefit. Thanks for feedback

@lmiller1990
Copy link
Contributor

lmiller1990 commented May 10, 2023

Sure, you should have access to devServerEvents when you create a dev server. It is passed in from the cypress.config.js, eg:

export default defineConfig({
  component: {
    async devServer({ specs, cypressConfig, devServerEvents }: DevServerOptions) {
                                            ^^^^^^^^^^^^^^^ here it is, it's an event emitter, emit things
      const { port, close } = await startDevServer(
        specs,
        cypressConfig,
        devServerEvents
      )

      return {
        port,
        close,
      }
    },
  },
})

You can then do something like this:

this.devServerEvents.emit('dev-server:compile:success')

this.devServerEvents.emit('dev-server:compile:success')

Search for devServerEvents in this directory and you can find them all. They go through a bunch of plumbing and end up getting responded to here which is in the browser - in this case, you can see 'dev-server:compile:success' leads to a function that calls rerun().

Just ask if you have more questions, I haven't worked on the dev servers in quite some time so I will also need to do a refresher. If you can make your code public, I could take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CT Issue related to component testing stage: needs investigating Someone from Cypress needs to look at this type: feature New feature that does not currently exist
Projects
None yet
Development

No branches or pull requests