> For the complete documentation index, see [llms.txt](https://devworkshops.gitbook.io/masteringvuejs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://devworkshops.gitbook.io/masteringvuejs/testing/integration-e2e-testing.md).

# Integration/E2E Testing

If you were brave enough to run `npm run test:e2e` in the overview section, that's what you were expecting to see

![](/files/-LW4ozWja_JfUQDoT-ub)

![](/files/-LW4p0UzNcv3TUaEU9g4)

![](/files/-LW4p3PmpJcfPhY-Q6B0)

## Creating test case

We're going to create a few meaningful integration tests here just to see if everything is in place. Be aware that this requires the project's dependencies to be running. If you're using a real API or **json-server**, make sure it's running.

Let's create a file called **general.js** under **tests/e2e/specs** and to start with we're going to test 2 things, whether the 404 route is working and if the home page contains the text that's supposed to contains.

{% code title="general.js" %}

```javascript
describe('General', () => {
    it('404 route should kick off', () => {
        cy.visit('/non-existing-route')
        cy.contains('h1', 'Oops')
    })

    it('home page shows welcome', () => {
        cy.visit('/')
        cy.contains('h1', 'Welcome')
    })
})
```

{% endcode %}

Now let's test some CRUD operations under **Suppliers**. This will a bit more complex, we'll test not only UI aspects when navigating to a route, but also whether it's able to connect to the api and successfully update records.

{% code title="suppliers.js" %}

```javascript
describe('Suppliers', () => {
    beforeEach(() => {
        cy.visit('/suppliers')
        cy.contains('h1', 'Suppliers')
    })

    it('Should open list of suppliers', () => {
        cy.get('table thead th').should('have.length', 4)
    })

    it('Should have 29 suppliers', () => {
        cy.get('table tbody tr').should('have.length', 29)
    })

    it('Should update existing supplier', () => {
        cy.get('table tbody tr:first button:first').click()
        cy.contains('h1', 'Supplier #')
        cy.get('input#companyNameField').type('NEW COMPANY')
        cy.get('button#saveButton').click()

        cy.get('table tbody td:first').should($td => {
            expect($td).to.contain('NEW COMPANY')
        })
    })

    it('Should create new supplier', () => {
        cy.get('button#addSupplier').click()
        cy.get('input#companyNameField').type('NEW COMPANY')
        cy.get('input#contactNameField').type('NEW CONTACT')
        cy.get('input#contactTitleField').type('CONTACT TITLE')
        cy.get('button#saveButton').click()
        cy.get('table tbody tr:last td:first').should($td => {
            expect($td).to.contain('NEW COMPANY')
        })
    })
})

```

{% endcode %}

Once this is created we can run it using the command `npm run test:e2e2`

![](/files/-LgRpwz9DRZBdbEsepG8)

For more information about the integration test API, check their [documentation](https://docs.cypress.io/api/introduction/api.html)

### Getting ready for automation

While opening the UI looks great, that's not ideal for automation. We want everything to run in the console, so let's update the **package.json** file and include a new script

{% code title="package.json" %}

```javascript
...
"test:e2e:headless": "vue-cli-service test:e2e --headless"
...
```

{% endcode %}

By using the flag `--headless`, Cypress is not going to open the whole UI, but run everything in the console like below:

![](/files/-LgRr10r9uRvvWj1h05Z)

Cool, that's a step forward. But you might now at this point that for the end-to-end tests to work, we need **json-server** to be running. It's alright to run json-server separately when it comes to running tests locally, but if you want to run the tests in an automated way in a continuous integration pipeline, you also need this to be kick off automatically.

For that we're going to leverage an npm package called **npm-run-all** which will run several scripts at once. You can install it by running `npm i npm-run-all` and once it's installed, we'll make changes to the **package.json**

{% code title="package.json" %}

```javascript
...
"json-server": "json-server db.json --port 3000",
"test:e2e:ci": "npm-run-all -p -r json-server test:e2e:headless"
...
```

{% endcode %}

Now if we run `npm run test:e2e:ci` it should start both **json-server** and the e2e tests.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://devworkshops.gitbook.io/masteringvuejs/testing/integration-e2e-testing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
