cypress
cypress copied to clipboard
Testing with Sail
Hey @JeffreyWay,
Another great package, thanks.
I just wanted to share my journey into getting to work this with Laravel Sail. We can add this to the Readme.md, adding configurations during the scaffold might be a bit of an overkill.
Follow the Installation
and Environment Handling
sections in Readme.md
Edit: cypress/support/index.js
to stop the swapping of the .env files
before(() => {
// cy.task('activateCypressEnvFile', {}, { log: false });
// cy.artisan('config:clear', {}, { log: false });
cy.refreshRoutes();
});
after(() => {
// cy.task('activateLocalEnvFile', {}, { log: false });
// cy.artisan('config:clear', {}, { log: false });
});
Run sail using .env.cypress
sail --env-file .env.cypress up
If you want to run tests on a separate database follow the rest of this guide.
Create a separate database
Sail does not provide sqlite, there might be a way to install it and configure it but I didn't find anything.
Credit to: https://michaelheap.com/laravel-sail-test-database/
Edit .env.cypress
DB_CONNECTION=mysql
DB_HOST=mysql_test
DB_DATABASE=
DB_USERNAME=root
Edit docker-compose.yml
to create a new database
services:
mysql_test:
image: "mysql:8.0"
environment:
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
networks:
- sail
@underthecocotree why stopping swap envs?
From memory, I think sail caches the environment variables on load/boot. That is where ‘sail —env-file .env.cypress’ comes in handy
Thinking about it I guess it wouldn’t hurt to keep it. It’s been a while since I changed any of that code.
Have you been successful with testing with the code present?
I'm a bit confused how to get this working with docker. I added the following to my docker-compose.yml
:
ui:
image: cypress/base:latest
It downloads the image but it doesn't seem to start correctly.
When I run sail npm install cypress --save-dev && sail npx cypress open
I get the following:
No version of Cypress is installed in: /home/sail/.cache/Cypress/10.1.0/Cypress
Please reinstall Cypress by running: cypress install
----------
Cypress executable not found at: /home/sail/.cache/Cypress/10.1.0/Cypress/Cypress
----------
Platform: linux-x64 (Ubuntu - 21.10)
Cypress Version: 10.1.0
And after running composer require laracasts/cypress --dev
, I'm unable to publish the boilerplate code with sail artisan cypress:boilerplate
:
Cypress not found. Please install it through npm and try again.
npm install cypress --save-dev && npx cypress open
Since I can't publish the boilerplate code, I'm unable to get the .env.cypress
file so it can be started with sail --env-file .env.cypress up
.
Any help would be much appreciated...
I am leaving this here in case someone is trying to run cypress in a separate container with laravel sail. The changes below will also add novnc in a separate container that will be used to show the cypress desktop app so that you don't have to make any config changes to your system or install an X11 server.
Add the following services in docker-compose.yml:
cypress:
build:
context: ./docker/cypress
args:
WWWUSER: "${WWWUSER}"
WWWGROUP: "${WWWGROUP}"
depends_on:
- laravel.test
- novnc
environment:
- CYPRESS_baseUrl=http://laravel.test:${APP_PORT:-80}
- DISPLAY=novnc:0.0
working_dir: /e2e
entrypoint: cypress open --project /e2e
volumes:
- ./:/e2e
networks:
- sail
novnc:
build:
context: ./docker/novnc
dockerfile: Dockerfile
args:
WWWUSER: "${WWWUSER}"
WWWGROUP: "${WWWGROUP}"
ports:
- "8080:8080"
networks:
- sail
Create the following folders:
- docker\cypress
- docker\novnc Add docker\cypress\Dockerfile:
FROM cypress/included:9.7.0
ARG WWWGROUP
ARG WWWUSER
RUN groupadd -o -g ${WWWGROUP} sail
# do not log creating new user, otherwise there could be a lot of messages
RUN useradd -r --no-log-init -o -u ${WWWUSER} -g sail sail
RUN install -d -m 0755 -o sail -g sail /home/sail
# move test runner binary folder to the non-root's user home directory
RUN mv /root/.cache /home/sail/.cache
USER sail
# show user effective id and group - it should be non-zero
# meaning the current user "node" is not root
RUN id
ENV CYPRESS_CACHE_FOLDER=/home/sail/.cache/Cypress
Add docker\novnc\Dockerfile:
FROM alpine:3.16
ARG WWWGROUP
ARG WWWUSER
# Setup demo environment variables
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
DISPLAY=:0.0
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
RUN apk update && \
apk add \
novnc@testing \
bash \
fluxbox \
terminus-font \
supervisor \
tigervnc
RUN ln -s /usr/share/novnc/vnc.html /usr/share/novnc/index.html
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
EXPOSE 8080
RUN addgroup -g ${WWWGROUP} sail
# do not log creating new user, otherwise there could be a lot of messages
RUN adduser --disabled-password --gecos "" --uid ${WWWUSER} --ingroup sail sail
RUN install -d -m 0755 -o sail -g sail /home/sail
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
And finally add docker\novnc\supervisord.conf:
[supervisord]
user=sail
nodaemon=true
logfile=/home/sail/supervisord.log
pidfile=/home/sail/supervisord.pid
[program:xvnc]
user=sail
command=/usr/bin/Xvnc -SecurityTypes=None -localhost=0 :0.0 -listen tcp -ac
autorestart=true
[program:novnc]
user=sail
command=/usr/bin/novnc_server --vnc localhost:5900 --listen 8080
autorestart=true
[program:fluxbox]
user=sail
command=fluxbox
autorestart=true
environment=HOME="/home/sail"
I am leaving this here in case someone is trying to run cypress in a separate container with laravel sail. The changes above will also add novnc in a separate container that will be used to show the cypress desktop app so that you don't have to make any config changes to your system or install an X11 server.
Add the following services in docker-compose.yml:
cypress: build: context: ./docker/cypress args: WWWUSER: "${WWWUSER}" WWWGROUP: "${WWWGROUP}" depends_on: - laravel.test - novnc environment: - CYPRESS_baseUrl=http://laravel.test:${APP_PORT:-80} - DISPLAY=novnc:0.0 working_dir: /e2e entrypoint: cypress open --project /e2e volumes: - ./:/e2e networks: - sail novnc: build: context: ./docker/novnc dockerfile: Dockerfile args: WWWUSER: "${WWWUSER}" WWWGROUP: "${WWWGROUP}" ports: - "8080:8080" networks: - sail
Create the following folders:
- docker\cypress
- docker\novnc Add docker\cypress\Dockerfile:
FROM cypress/included:9.7.0 ARG WWWGROUP ARG WWWUSER RUN groupadd -o -g ${WWWGROUP} sail # do not log creating new user, otherwise there could be a lot of messages RUN useradd -r --no-log-init -o -u ${WWWUSER} -g sail sail RUN install -d -m 0755 -o sail -g sail /home/sail # move test runner binary folder to the non-root's user home directory RUN mv /root/.cache /home/sail/.cache USER sail # show user effective id and group - it should be non-zero # meaning the current user "node" is not root RUN id ENV CYPRESS_CACHE_FOLDER=/home/sail/.cache/Cypress
Add docker\novnc\Dockerfile:
FROM alpine:3.16 ARG WWWGROUP ARG WWWUSER # Setup demo environment variables ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ DISPLAY=:0.0 RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories RUN apk update && \ apk add \ novnc@testing \ bash \ fluxbox \ terminus-font \ supervisor \ tigervnc RUN ln -s /usr/share/novnc/vnc.html /usr/share/novnc/index.html COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf EXPOSE 8080 RUN addgroup -g ${WWWGROUP} sail # do not log creating new user, otherwise there could be a lot of messages RUN adduser --disabled-password --gecos "" --uid ${WWWUSER} --ingroup sail sail RUN install -d -m 0755 -o sail -g sail /home/sail CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
And finally add docker\novnc\supervisord.conf:
[supervisord] user=sail nodaemon=true logfile=/home/sail/supervisord.log pidfile=/home/sail/supervisord.pid [program:xvnc] user=sail command=/usr/bin/Xvnc -SecurityTypes=None -localhost=0 :0.0 -listen tcp -ac autorestart=true [program:novnc] user=sail command=/usr/bin/novnc_server --vnc localhost:5900 --listen 8080 autorestart=true [program:fluxbox] user=sail command=fluxbox autorestart=true environment=HOME="/home/sail"
@parapente not sure if I'm missing something here but when I run sail npx cypress open
after following all your steps, I get the following:
No version of Cypress is installed in: /home/sail/.cache/Cypress/10.10.0/Cypress
Please reinstall Cypress by running: cypress install
----------
Cypress executable not found at: /home/sail/.cache/Cypress/10.10.0/Cypress/Cypress
----------
Platform: linux-x64 (Ubuntu - 21.10)
Cypress Version: 10.10.0
@matthewknill first of all try to match the versions of cypress you want to use. In the above instructions I had
FROM cypress/included:9.7.0
because I used an old project with laravel 8. Make sure to change to the one you have installed in your project with npm.
Then you don't need to run sail npx cypress open
as cypress is auto started. You just browse http://localhost:8080
and you should see novpn. Click "Connect" and from the gear on the left side of the screen choose scaling mode to remote resize.
If for some reason you close the cypress application, you can restart it running docker-compose start cypress
.
I haven't used cypress 10 yet but I'm really interested in its component testing feature, so if I find something not working, I will post further instructions.
@matthewknill first of all try to match the versions of cypress you want to use. In the above instructions I had
FROM cypress/included:9.7.0
because I used an old project with laravel 8. Make sure to change to the one you have installed in your project with npm.
Then you don't need to run
sail npx cypress open
as cypress is auto started. You just browsehttp://localhost:8080
and you should see novpn. Click "Connect" and from the gear on the left side of the screen choose scaling mode to remote resize.If for some reason you close the cypress application, you can restart it running
docker-compose start cypress
.I haven't used cypress 10 yet but I'm really interested in its component testing feature, so if I find something not working, I will post further instructions.
Fantastic, got it working thanks! Quite annoying to get it working with WSL2 on Windows without using a container. You can use the following to make the VNC fullscreen (set Remote Resizing):
Worked (almost) perfectly on WSL2. Thanks @matthewknill @parapente
Everything comes up in the VNC window but when running the default test I get an error failed trying to load http://laravel.test:80/
connection refused to 127.0.0.1:80.
Shouldn't it look for laravel.test on the internal Sail IP address?
UPDATE
.env.cypress
is initially a copy of .env
and had another value for APP_URL_BASE
instead of laravel.test
Once corrected everything works fine :)
Hello @matthewknill @parapente
Have either of you tried to get this working with subdomains? Specifically I'd like to to test a "tenancy for laravel" https://github.com/archtechx/tenancy application but can't find a way to get cypress to connect to tenants which are subdomains, only the central domain is ok.
@stancl - have you ever got cypress working?
I've never used it unfortunately
Hello @matthewknill @parapente
Have either of you tried to get this working with subdomains? Specifically I'd like to to test a "tenancy for laravel" https://github.com/archtechx/tenancy application but can't find a way to get cypress to connect to tenants which are subdomains, only the central domain is ok.
@stancl - have you ever got cypress working?
I'm actually looking to use this package in the future. You could get this working by just changing the baseUrl
in cypress.config.js
though right (I haven't tested this)?
I'm finding that sail --env-file .env.cypress up
does not seem to use my .env.cypress
for some reason and just uses the standard database in .env
. I followed the exact procedure above and still can't get it to use a different database even after clearing the cache and everything.
@matthewknill you should probably run php artisan cypress:boilerplate
to install the boilerplate code needed for testing laravel apps. If you install the boilerplate from the package it should read the .env.cypress file before every test.
@matthewknill @parapente - I've got this working for @stancl Tenancy for Laravel by configuring an alias for laravel.test
in docker-compose.yml
:
networks:
sail:
aliases:
- testing.laravel.test
This means that any calls to the testing hostname from cypress or dusk are resolved to the application container using dockers internal dns magic.
My complete file is:
# For more information: https://laravel.com/docs/sail
version: '3'
services:
laravel.test:
build:
context: ./vendor/laravel/sail/runtimes/8.1
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.1/app
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- '.:/var/www/html'
networks:
sail:
aliases:
- testing.laravel.test
depends_on:
- mysql
- redis
mysql:
build:
context: ./docker/mysql
dockerfile: Dockerfile
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}" ]
retries: 3
timeout: 5s
redis:
image: 'redis:alpine'
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sail-redis:/data'
networks:
- sail
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
retries: 3
timeout: 5s
mailhog:
image: 'mailhog/mailhog:latest'
ports:
- '${FORWARD_MAILHOG_PORT:-1025}:1025'
- '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
cypress:
build:
context: ./docker/cypress
args:
WWWUSER: "${WWWUSER}"
WWWGROUP: "${WWWGROUP}"
depends_on:
- laravel.test
- novnc
environment:
- CYPRESS_baseUrl=http://laravel.test:${APP_PORT:-80}
- DISPLAY=novnc:0.0
working_dir: /e2e
entrypoint: cypress open --project /e2e
volumes:
- ./:/e2e
networks:
- sail
novnc:
build:
context: ./docker/novnc
dockerfile: Dockerfile
args:
WWWUSER: "${WWWUSER}"
WWWGROUP: "${WWWGROUP}"
ports:
- "8080:8080"
networks:
- sail
selenium:
image: 'selenium/standalone-chrome'
volumes:
- '/dev/shm:/dev/shm'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
sail-redis:
driver: local
Thank you @parapente . I have done the steps from you. But I got this error when execute sail up:
ERROR [ark-novnc 6/8] RUN addgroup -g 20 sail
@protocyber you use a value for WWWGROUP that clashes with a group that already exists in the novnc container. Use id -g
to see the group your user is in and try that one instead (usually 1000+).
I'm using mac. And by default any user is a member of staff
group which has ID of 20. Should I create another group. Maybe called group username
like in Linux?
Update: I have create a new group and set this as my default group
But I there is another problem, the novnc cannot start:
INFO success: novnc entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
INFO exited: novnc (exit status 1; not expected)
Meanwhile there is also error in cypress container:
cypress-1 | qemu: uncaught target signal 11 (Segmentation fault) - core dumped
cypress-1 | The Test Runner unexpectedly exited via a exit event with signal SIGSEGV
cypress-1 |
cypress-1 | Please search Cypress documentation for possible solutions:
cypress-1 |
cypress-1 | https://on.cypress.io
cypress-1 |
cypress-1 | Check if there is a GitHub issue describing this crash:
cypress-1 |
cypress-1 | https://github.com/cypress-io/cypress/issues
cypress-1 |
cypress-1 | Consider opening a new issue.
cypress-1 |
cypress-1 | ----------
cypress-1 |
cypress-1 | Platform: linux-x64 (Debian - 11.3)
cypress-1 | Cypress Version: 9.7.0
@protocyber there is a group named dialout in the novnc groups file with group id 20. Try modifying the novnc/Dockerfile by adding the following line before addgroup:
delgroup dialout
Thank you for responding @parapente. Unfortunately the problem still the same.
@protocyber there is a group named dialout in the novnc groups file with group id 20. Try modifying the novnc/Dockerfile by adding the following line before addgroup:
delgroup dialout
@protocyber Did you return WWWGROUP to 20?
My novnc/Dockerfile

Build log

sail up log...

@protocyber Here are some things to check:
- Take everything down using
sail down
and rebuild containers in case one of them still uses the wrong group number. - check file permissions of your project folder in case something got set with wrong user/group id. In case your project doesn't require special file permissions your can just run
chown -R <user>:<group> .
inside the project folder. - The segfault for cypress isn't something that you should worry about that much. If for some reason cypress gets started before fluxbox and Xvnc, it usually crashes. Running
sail restart cypress
should start the desktop app. Take a look at the novnc log when it starts to see why Xnvc doesn't start as it is needed for everything else.
Thanks very much for your solution, @parapente! I needed to make a couple of additions:
- Added
py3-pip
to the list of apk packages to install innovnc/Dockerfile
. - Added
RUN pip3 install websockify
tonovnc/Dockerfile
.
You are welcome @trashbat! Indeed the alpine package for novnc is now missing websockify so your proposed solution I think is the best one you can use.
After the latest updates to Alpine Linux packages, docker fails to build the novnc container. Updating to the latest image (3.18) novnc builds correctly.
docker\novnc\Dockerfile:
FROM alpine:3.18
Is there a way a way to Cypress without an VNC, and still have all the features?
Is there a way a way to Cypress without an VNC, and still have all the features?
@Thinkro As Laravel Sail runs inside a Linux container you would need to use an X server for the GUI of Cypress to appear. If you are running a Linux desktop you can use xauth to allow applications from the container to appear on your screen without using vnc. If you are not on a Linux desktop, you would need an X server for Cypress to appear. It's a bit of a hassle to configure xauth and you might even end up compromising your security if you don't configure it correctly. I prefer to use novnc as it is easy to run in linux, macos and windows.
Wanted to share a recipe to get Sail and Cypress to work nice together. We're running 2 instances of all our services, so that each time we wipe the db/meilisearch db we don't have to login/resync meilisearch etc.
This way you can do cypress up
(we reuse sail npm run dev
, so no need to do that)
https://gist.github.com/prebenvendo/6b9ae9790e4a321f5d253d3d2f016162
Let me know if anything is unclear.