├── .devcontainer ├── Dockerfile ├── devcontainer.json └── docker-compose.yml ├── .gitignore ├── README.md ├── cypress └── integration │ └── example.spec.js └── package.json /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG VARIANT=16-bullseye 2 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT} 3 | 4 | # https://docs.cypress.io/guides/continuous-integration/introduction#Dependencies 5 | RUN apt-get update && \ 6 | export DEBIAN_FRONTEND=noninteractive && \ 7 | apt-get -y install --no-install-recommends \ 8 | libgtk2.0-0 \ 9 | libgtk-3-0 \ 10 | libgbm-dev \ 11 | libnotify-dev \ 12 | libgconf-2-4 \ 13 | libnss3 \ 14 | libxss1 \ 15 | libasound2 \ 16 | libxtst6 xauth xvfb 17 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "dockerComposeFile": "docker-compose.yml", 3 | "service": "development", 4 | "forwardPorts": [8080], 5 | "postCreateCommand": "yarn install && yarn cy install" 6 | } 7 | -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | development: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | command: sleep infinity 9 | environment: 10 | DISPLAY: ":14" 11 | LIBGL_ALWAYS_INDIRECT: 0 12 | volumes_from: 13 | - x11-bridge:rw 14 | depends_on: 15 | - x11-bridge 16 | 17 | x11-bridge: 18 | image: jare/x11-bridge 19 | 20 | volumes: 21 | - "/tmp/.X11-unix:/tmp/.X11-unix:rw" 22 | 23 | ports: 24 | - "8080:8080" 25 | 26 | restart: always 27 | 28 | environment: 29 | MODE: tcp 30 | XPRA_HTML: "yes" 31 | DISPLAY: ":14" 32 | XPRA_TCP_PORT: "8080" 33 | XPRA_PASSWORD: MUST_BE_SOMETHING 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | 4 | # Generated by Cypress 5 | cypress.json 6 | cypress/fixtures 7 | cypress/plugins 8 | cypress/support -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cypress-codespaces-example 2 | 3 | Setup based on https://github.com/cypress-io/cypress-documentation/issues/2956#issuecomment-930527836. 4 | 5 | For playwright see https://github.com/AriPerkkio/cypress-codespaces-example/tree/playwright. 6 | 7 | - Click link https://localhost:8080 8 | - Login using `MUST_BE_SOMETHING` as password 9 | - Run `yarn cy open` 10 | -------------------------------------------------------------------------------- /cypress/integration/example.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // Welcome to Cypress! 4 | // 5 | // This spec file contains a variety of sample tests 6 | // for a todo list app that are designed to demonstrate 7 | // the power of writing tests in Cypress. 8 | // 9 | // To learn more about how Cypress works and 10 | // what makes it such an awesome testing tool, 11 | // please read our getting started guide: 12 | // https://on.cypress.io/introduction-to-cypress 13 | 14 | describe('example to-do app', () => { 15 | beforeEach(() => { 16 | // Cypress starts out with a blank slate for each test 17 | // so we must tell it to visit our website with the `cy.visit()` command. 18 | // Since we want to visit the same URL at the start of all our tests, 19 | // we include it in our beforeEach function so that it runs before each test 20 | cy.visit('https://example.cypress.io/todo') 21 | }) 22 | 23 | it('displays two todo items by default', () => { 24 | // We use the `cy.get()` command to get all elements that match the selector. 25 | // Then, we use `should` to assert that there are two matched items, 26 | // which are the two default items. 27 | cy.get('.todo-list li').should('have.length', 2) 28 | 29 | // We can go even further and check that the default todos each contain 30 | // the correct text. We use the `first` and `last` functions 31 | // to get just the first and last matched elements individually, 32 | // and then perform an assertion with `should`. 33 | cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') 34 | cy.get('.todo-list li').last().should('have.text', 'Walk the dog') 35 | }) 36 | 37 | it('can add new todo items', () => { 38 | // We'll store our item text in a variable so we can reuse it 39 | const newItem = 'Feed the cat' 40 | 41 | // Let's get the input element and use the `type` command to 42 | // input our new list item. After typing the content of our item, 43 | // we need to type the enter key as well in order to submit the input. 44 | // This input has a data-test attribute so we'll use that to select the 45 | // element in accordance with best practices: 46 | // https://on.cypress.io/selecting-elements 47 | cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) 48 | 49 | // Now that we've typed our new item, let's check that it actually was added to the list. 50 | // Since it's the newest item, it should exist as the last element in the list. 51 | // In addition, with the two default items, we should have a total of 3 elements in the list. 52 | // Since assertions yield the element that was asserted on, 53 | // we can chain both of these assertions together into a single statement. 54 | cy.get('.todo-list li') 55 | .should('have.length', 3) 56 | .last() 57 | .should('have.text', newItem) 58 | }) 59 | 60 | it('can check off an item as completed', () => { 61 | // In addition to using the `get` command to get an element by selector, 62 | // we can also use the `contains` command to get an element by its contents. 63 | // However, this will yield the