I just have a question around best method to start my react app when I run cypress test. Right now the way its setup for me I need to start my server then run cypress test. I would like a single command to start react app -> run Cypress test.
I am new to both react and cypress
My package.json looks like this
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "cypress run",
"eject": "react-scripts eject"
},
Currently I need to run npm start then in another window npm test
I tried to start and run test in a single line but I could not get it to work. It just started react app and did nothing else.
I wrote this up recently as part of a series on TDD in JS, you can read the full article on my blog.
First, install some useful helper dependencies:
$ npm install concurrently cross-env wait-on
Then add some extra scripts to the package.json:
"e2e:ci": "concurrently -k -s first \"npm:e2e:ci:*\"",
"e2e:ci:app": "cross-env BROWSER=none PORT=4321 npm start",
"pree2e:ci:run": "wait-on -t 30000 http-get://localhost:4321",
"e2e:ci:run": "cross-env CYPRESS_BASE_URL=http://localhost:4321 npm run e2e",
So what does that do? When we run npm run e2e:ci, the concurrently script is going to run two things in parallel for us:
e2e:ci:app: Run the app using npm start, with some environment variables set via cross-env (this allows it to work on *nix and Windows):
BROWSER=none stops the browser from popping up and taking over the screen [this is the default behaviour of a React app created by CRA, which the article was using]; and
PORT=4321 runs the app on the specified port (so we can still have a version running on port 3000 without causing any conflicts).
e2e:ci:run: Run the E2E tests in a two-step process:
The pre script runs first, and uses wait-on to wait for up to 30,000ms for the app to be running on the specified port; then
If that works (i.e. the app starts in less than 30s) run the actual tests, with the baseUrl configuration overridden to point to the right place.
The other configuration options passed to concurrently itself are:
-k, meaning stop all of the other processes when one exits (in this case we expect our tests to exit at some point and want to stop the app when they do); and
-s first, meaning that the output of the overall command is the output of the first one to exit (i.e. output from the e2e:ci command should be the output from the tests).
Building on the answer by jonrsharpe, I also needed to launch my (golang, though the implementation language doesn't really matter) api server, and I'm running tests via wdio. It uses the same toolset as his answer but with an extra step:
"e2e:ci": "concurrently -k -s first \"npm:e2e:ci:*\"",
"e2e:ci:server": "cross-env SERVER_PORT=40001 ./launchServer.sh",
"pree2e:ci:app": "wait-on -t30000 http-get://localhost:40001/state",
"e2e:ci:app": "cross-env BROWSER=none PORT=40002 npm start",
"pree2e:ci:run": "wait-on -t 30000 http-get://localhost:40002",
"e2e:ci:run": "npx wdio run ./wdio.conf.js --baseUrl http://localhost:40002"
The two extra scripts are:
e2e:ci:server which runs a script to launch the server
pree2e:ci:app just waits until the server is running. Note that it's not just waiting on "/" -- my api server 404s on root requests, and wait-on needs to get a 2xx response, so the http-get url needs to be a valid api endpoint ("/state").
It's also worth noting that wdio just uses an extra command line argument to set the base url instead of the env var in the original cypress solution.
Related
Scenario:
I have cypress tests that we run on multiple environments( more than 8), each environment with a separate domain, so we have configured all the domains in cypress.json file under env, now I need to pass the domain dynamically, i.e, from command line and be able to pick it and run the tests on respective domain. but I'm not sure how I can grab that value passed in command line.
Note: I have tried process.env method but did not work.
Code looks like this :
Cypress.json
{
"env": {
"domain1": xyz.com,
"domain2": abc.com,
"domain3": 123.com
}
}
package.json :
{
scripts: {
"test": "npm run cypress open --env domian= $1
}
}
$1 is suppose to get me the command line argument"
From my files under integration folder, Cypress.env(Cypress.env().domain) will/should fetch me the right domain.
However I'm receiving $1 as domain value.
Please help.
Can you share how $1 is supposed to reference the env file? I don't understand that part.
In the meantime, here is an alternative answer to your problem. (just tested it out)
You can write several test scripts which each provide a different domain address.
{
scripts: {
"test1": "npm run cypress open --env domian=xyz.com",
"test2": "npm run cypress open --env domian=abc.com",
"test3": "npm run cypress open --env domian=123.com"
}
}
I would like to run an integration test with msw + cypress + start-server-and-test
1- I have msw as a mock on the react app itself (port 3000)
2- I have a socket.io server in port 5000
my question is how to run it properly to make sure start-server-and-test will handle it
I tried with concurrently. but I am not sure if this is the way
my package.json:
"socket-server": "node test/socket/index.js"
"start-server": "concurrently \"npm run socket-server\" \"cross-env NODE_ENV=development craco start\"",
"test:e2e:ci": "start-server-and-test start-server \"3000\" cypress:headless",
another issue is when I changed the port from 3000 to smth that unavailable the app stuck and the test does not close the app
thanks
OK fixed by use the "start-test" from the start-server-and-test library
so in order to run both socket server + api or any list of server you can run this:
start-test <first command> <first resource> <second command> <second resource> <test command>
i.e
{
"scripts": {
"test": "node src/test",
"start:api": "node src/api",
"start:server": "node src/server",
"test:all": "start-test start:api 3000 start:server 8080 test"
}
}
this is also written in the docs
https://github.com/bahmutov/start-server-and-test
I am facing an issue while building my React project using GitHub as a repository, Travis as CI with AWS ElasticBeanStalk as a service to run my app using Docker. I am able to run my test suite but after that, it is not deploying my app on AWS and also not getting any error in Travis console except below:
Below is my Travis .yml file configuration:
language: generic
services:
- docker
before_install:
- docker build -t heet1996/my-profile -f Dockerfile.dev .
script:
- docker run heet1996/my-profile npm run test -- --coverage
deploy:
provider: elasticbeanstalk
region: "us-east-1"
app: "My-profile"
env: "MyProfile-env"
bucket_name: "elasticbeanstalk-us-east-1-413920612934"
bucket_path: "My-profile"
on:
branch: master
access_key_id: $AWS_ACCESS_KEY
secret_access_key: "$AWS_SECRET_KEY"
Let me know if you need more information
A couple things you could try:
Your script command needs to set the environment var CI=true
So
script:
- docker run heet1996/my-profile npm run test -- --coverage
Becomes
script:
- docker run -e CI=true heet1996/my-profile npm run test -- --coverage
Also AWS needs the access variables to be named differently.
Change
access_key_id: $AWS_ACCESS_KEY
secret_access_key: "$AWS_SECRET_KEY"
To
access_key_id: "$AWS_ACCESS_KEY_ID"
secret_access_key: "$AWS_SECRET_ACCESS_KEY"
Using the option --coverage, your test will hang, waiting for input. Hence the message: "...no output has been received in the last 10m0s...".
At a certain point, --coverage was probably able to stop tests (as some used for that purpose), but I guess it was not meant for that and subsequent versions of docker removed that behavior.
Your test must conclude and the conclusion be a success for the deployment by Travis to begin.
Use instead the option --watchAll=false. So you should have:
...
script:
- docker run heet1996/my-profile npm run test -- --watchAll=false
...
That would take care of the obvious issue of your test never concluding (that could be the only issue). Afterward, make sure that your tests are successful. Then, you can worry about other issues such as authentication on AWS, etc...
I'm trying to setup my webpack instance with webpack-dev-server.
I pass into scripts a setting for increase header size "--max-http-header-size=100000".
"dev": "npm run options-to-dev && env targets=manager && node --max-http-header-size=100000 webpack-dev-server --host 0.0.0.0 --progress --config webpack.config.js"
on execution script "dev" I got an error
$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
^^^^^^^
SyntaxError: missing ) after argument list
at Module._compile (internal/modules/cjs/loader.js:891:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
at internal/main/run_main_module.js:17:11
without "node --max-http-header-size=100000" webpack working perfect.
Problem was in my file webpack-dev-server file. I pass instead webpack-dev-server this line ../../node_modules/webpack-dev-server/bin/webpack-dev-server.js
"dev:windows": "npm run options-to-dev && env targets=customer && node --max-http-header-size=100000 ../../node_modules/webpack-dev-server/bin/webpack-dev-server.js --host 0.0.0.0 --progress --config webpack.config.js"
If you want to run webpack-dev-server with that option then use following:
{
"scripts": "NODE_OPTIONS='--max-http-header-size=100000' webpack-dev-server"
}
A little mention about it can be found at the bottom of this documentation page: https://webpack.js.org/configuration/dev-server/
Hard to find without using search option ;)
It took me some time to figure out. Its essential not a problem with webpack devserver, nuxt or other framework running on top.
Its node that enforces the limit due to avoiding DDOS attacks for any webserver running on a node.
You can when starting node giving the argument --max-http-header-size to change the value.
But many of us that use a framework, react, or nuxt on top is not starting node ourserlf so it is hard to find exactly what to do and having to start everything ourselves is not trivial.
cross-env is really nice, allowing you to set environment variables and node do accept a NODE_OPTIONS environment variable where custom arguments all can be set.
See the example I used o a nuxt project here:
"scripts": {
"build": "nuxt-ts build",
"dev": "cross-env NODE_OPTIONS=--max-http-header-size=200000 DEBUG='express:*' authority=.... resourceApi=... nuxt-ts --port 3001",
"generate": "nuxt-ts generate",
"precommit": "npm run lint",
"start": "nuxt-ts start --port 3001"
},
where I changed the normal dev:"nuxt-ts" option to use cross-env and setting max HTTP header.
Hopefully, this can help others.
I am getting invalid host header problem while i am trying to server my application by ng serve --host 0.0.0.0 . I have tried the following.
1.install -g angular-cli
2. cd to that app-directory
3. change port in angular-cli.json
"defaults": {
"styleExt": "css",
"component": {},
"serve": {
"port": 1337
}
}
ng serve --host 0.0.0.0
Requested url in browser is http://port-1337.angular2-jobproject0889272.codeanyapp.com/
I was looking to sovle a different problem and came across an answer that may work for you.
ng serve --port 8080 --host 0.0.0.0 --disableHostCheck true
Angular-cli GitHub
If I'm understanding your question correctly, your issue could be stemming from Webpack's security impl.
As the Angular CLI uses Webpack by default to bundle your app, you have to abide by its requirements when using "ng serve". App bundles produced by Webpack now require the Host header of the request to match the listening address OR the host provided in the public option.
The public option is a --public flag passed with the "ng serve" command. On CodeAnywhere you should most likely care to indicate a port # as well. A valid "ng serve" command could look like this:
$ ng serve --host 0.0.0.0 --port 3000 --public myproject-myusername.codeanyapp.com
(For HTTPS service, CodeAnywhere requires you use port 3000)
You can find your specific value for the --public flag in your CodeAnywhere IDE by right-clicking on your project's tree view Connection icon and selecting the "info" option.
To simplify things, you can set this up in your package.json file and then start the Angular server with the command:
$ npm start
For example, you can modify the "start" element of the package.json "scripts" entry as follows:
"scripts": {
"ng": "ng",
"start": "ng serve --host 0.0.0.0 --port 3000 --public myproject-myusername.codeanyapp.com"
}
Hopefully this info is applicable to the issue you are facing. Good Luck!