Curso intermediario da Escola Talking Abount Testing de Cypress
Durante o curso de testes automatizados com o Cypress foi aprendido
- Como configurar o ambiente local de desenvolvimento
- Como instalar e configurar o Cypress
- Como criar testes automatizados de interface gráfica de usuário
- Como criar testes automatizados de API (com feedback visual no navegador)
- Como testar APIs que necessitam um token de acesso
- Como criar testes otimizados e direto-ao-ponto
- Como salvar a sessão do usuário no navegador para posterior restauração
- Como validar se a sessão do usuário ainda é válida e como lidar com isso quando a mesma é invalidada
- Como fazer a limpeza e criação da massa de dados antes do teste começar
- Como proteger dados sensíveis, tais como senhas e tokens de acesso
- Como organizar os testes e comandos customizados em diferentes "camadas" (API, CLI, GUI)
- Como estruturar os testes pensando em pré-condições, ações e resultados esperados
- Como gerar dados aleatórios para uso nos testes automatizados
- Como habilitar funcionalidades experimentais do Cypress
- Como executar comandos à nível de sistema operacional
- E como testar a leitura de arquivos
Antes de começar, garanta que os seguintes requisitos sejam atendidos:
- Computador com no mínimo 2 cores
- e no mínimo 8 GB de memória RAM
Além disso, garanta que os seguintes sistemas estejam instalados no seu computador:
- Docker (estou usando a versão 20.10.22)
- git (estou usando a versão 2.39.0)
- Node.js (estou usando a versão v16.18.0)
- npm (estou usando a versão 9.3.0)
- Visual Studio Code (versão 1.74.3) ou alguma outra IDE de sua preferência
Para verificar as versões do Docker, git, Node.js e npm como o seguinte comando
docker --version && git --version && node --version && npm --version
O GitLab possui diversas funcionalidades, porém, duruante o curso fui tratado as seguintes:
- Login
- Logout
- Criação de projeto
- Criação de issue
- Adição de uma etiqueta (label) à uma issue
- Adição de um marco (milestone) a uma issue
- Git clone
Com o docker rodando no seu computador, execute o comando
docker run --publish 80:80 --publish 22:22 --hostname localhost wlsf82/gitlab-ce
e aguarde até o ambiente inicializar.
🕐 Isso por levar alguns minutos.
☕ Portanto, recomendo pegar um café (ou um chá) enquanto aguarda.
Depois de alguns minutos, acesse a URL http://localhost para definir a senha do usuário root
.
Ao acessar a URL http://localhost, deverá aparece ma página assim, no qual deve ser traocado a senha do usuário root
- Faça login com o usuário
root
com a senha definida na seção anterior - Clique no avatar do usuário no canto superior direito da tela; clique no link Settings;
- Clique na opção Access Tokens (no menu lateral esquerdo)
- No campo nome, digite o valor
cypress-intermediario-v2
; na seção Scopes marque a opção api; - Então, clique no botão Create personal access token.
Uma mensagem de que o token foi criado com sucesso deve ser exibida, além do token propriamente dito. Copie o token.
- No terminal de linha de comando, digite o seguinte comando e pressione ENTER
ssh-keygen -t ed25519 -C "root@example.com"
- Será solicitado um caminho para salvar a chave. Pressione
ENTER
para aceitar o caminho padrão - Será solicitada uma senha. Pressione
ENTER
para que a senha não seja necessária - Será solicitado que repita a senha. Pressione
ENTER
novamente para que a senha não seja necessária - De novo no terminal de linha de comando, digite o seguinte comando e pressione
ENTER
para copiar a chave pública recém-criada para a área de transferênciaclip < ~/.ssh/id_ed25519.pub
(no caso de windows) - Logado na aplicação com o usuário root, clique no avatar do usuário no canto superior direito da tela; clique no link Settings; e então, clique na opção SSH Keys (no menu lateral esquerdo)
- Cole sua chave SSH pública no campo key. O campo Title deve ser automaticamente preenchido
- Por fim, clique no botão
Add key
.
- Acesse a URL https://github.com/wlsf82/cypress-intermediario-v2
- Clique no botão Clone
- Escolha uma das opções (Clone with SSH ou Clone with HTTPS) e então clique no botão Copy URL ao lado do campo da opção escolhida
No terminal de linha de comando, na raiz do projeto, execute o comando
npm i @faker-js/faker@7.6.0 cypress@12.0.2 cypress-plugin-api@2.6.1 -D
Este comando irá instalar o Cypress e outras libs como dependências de desenvolvimento, além de criar o arquivo
package-lock.json
e o diretórionode_modules/
, para onde é feito o download de todas as dependências
No terminal de linha de comando, na raiz do projeto, execute o comando
npx cypress open
Este comando irá abrir a Cypress App, a qual vai guiar na criação do projeto de testes end-to-end (E2E).
- Clique no botão para a criação de um projeto de testes end-to-end (E2E Testing);
- Aceite os arquivos de configuração clicando no botão Continue;
- Selecione o navegador
Electron
e clique no botãoStart E2E Testing in Electron
; - Crie um primeiro arquivo de teste clicando na opção
Create new emtpy spec
; - Nomeie o arquivo como
login.cy.js
; - clique no botão Create spec;
- e então, confirme clicando no botão
Ok
,run the spec
; - Após a execução do arquivo recém-criado, feche o navegador Electron.
Configurações para relizar teste com o Cypress
- Feche a Cypress App
- Abra o arquivo
cypress.config.js
criado na raiz do projeto e altere o seu conteúdo pelo seguinte:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost',
},
fixturesFolder: false,
video: false,
})
- Ainda na raiz do projeto, crie um arquivo chamado
cypress.env.json
com os seguintes dados:
{
"user_name": "root",
"user_password": "password-do-usuario-root-definido-anteriormente",
"gitlab_access_token": "access-token-criado-anteriormente"
}
- Na pasta
cypress/
, crie uma subpasta chamadadownloads/
.
Teste no login
- No diretório
cypress/e2e/
, crie um diretório chamadogui/
(graphical user interface) - Então, mova o arquivo
login.cy.js
para o diretório recém-criado e modifique os seus dados para o seguinte:
describe('Login', () => {
it('successfully', () => {
cy.login()
cy.get('.qa-user-avatar').should('be.visible')
})
})
- Dentro do diretório
cypress/support/
, renomeie o arquivocommands.js
porgui_commands.js
e altere seu conteúdo pelo seguinte:
Cypress.Commands.add('login', (
user = Cypress.env('user_name'),
password = Cypress.env('user_password'),
) => {
const login = () => {
cy.visit('/users/sign_in')
cy.get("[data-qa-selector='login_field']").type(user)
cy.get("[data-qa-selector='password_field']").type(password, { log: false })
cy.get("[data-qa-selector='sign_in_button']").click()
}
login()
})
- No diretório
cypress/support/
, altere os dados do arquivo e2e.js pelo seguinte:
import './gui_commands'
- Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando para executar o novo teste em modo headless.
npx cypress run --spec cypress/e2e/gui/login.cy.js
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ login.cy.js 00:02 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:02 1 1 - - -
Teste logout
Criar um teste automatizado que exercita a funcionalidade de logout via interface gráfica de usuário.
- Dentro do diretrório
cypress/e2e/gui/
, crie um arquivo chamadologout.cy.js
com os seguintes dados:
describe('Logout', () => {
beforeEach(() => {
cy.login()
cy.visit('/')
})
it('successfully', () => {
cy.logout()
cy.url().should('be.equal', `${Cypress.config('baseUrl')}/users/sign_in`)
})
})
- No diretório
cypress/support/
, atualize o arquivogui_commands.js
com o commando logout, conforme abaixo:
Cypress.Commands.add('logout', () => {
cy.get('.qa-user-avatar').click()
cy.contains('Sign out').click()
})
- Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando para executar o novo teste em modo headless.
npx cypress run --spec cypress/e2e/gui/logout.cy.js
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ logout.cy.js 00:03 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:03 1 1 - - -
Criar um teste automatizado que exercita a funcionalidade de criação de projeto via interface gráfica de usuário.
GUI
- Dentro do diretrório
cypress/e2e/gui/
, crie um arquivo chamadocreateProject.cy.js
com os seguintes dados:
import { faker } from '@faker-js/faker'
describe('Create Project', () => {
beforeEach(() => {
cy.login()
})
it('successfully', () => {
const project = {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
cy.gui_createProject(project)
cy.url().should('be.equal', `${Cypress.config('baseUrl')}/${Cypress.env('user_name')}/${project.name}`)
cy.contains(project.name).should('be.visible')
cy.contains(project.description).should('be.visible')
})
})
- No diretório
cypress/support/
, atualize o arquivo gui_commands.js com o commandogui_createProject
, conforme abaixo:
Cypress.Commands.add('gui_createProject', project => {
cy.visit('/projects/new')
cy.get('#project_name').type(project.name)
cy.get('#project_description').type(project.description)
cy.get('.qa-initialize-with-readme-checkbox').check()
cy.contains('Create project').click()
})
- Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando para executar o novo teste em modo headless.
npx cypress run --spec cypress/e2e/gui/createProject.cy.js
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ createProject.cy.js 00:06 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:06 1 1 - - -
Funcionalidade para salva a sessão do usuário
Use a funcionalidade cy.session()
para salvar a sessão do usuário no navegador, e assim, otimizar os testes, fazendo login via GUI somente para o teste que faz sentido.
- No arquivo
cypress/support/gui_commands.js
, altere o comando customizado de login pelo seguinte:
Cypress.Commands.add('login', (
user = Cypress.env('user_name'),
password = Cypress.env('user_password'),
{ cacheSession = true } = {},
) => {
const login = () => {
cy.visit('/users/sign_in')
cy.get("[data-qa-selector='login_field']").type(user)
cy.get("[data-qa-selector='password_field']").type(password, { log: false })
cy.get("[data-qa-selector='sign_in_button']").click()
}
const options = {
cacheAcrossSpecs: true,
}
if (cacheSession) {
cy.session(user, login, options)
} else {
login()
}
})
- No arquivo
cypress/e2e/gui/login.cy.js
, altere seu conteúdo para o seguinte:
describe('Login', () => {
it('successfully', () => {
const user = Cypress.env('user_name')
const password = Cypress.env('user_password')
const options = { cacheSession: false }
cy.login(user, password, options)
cy.get('.qa-user-avatar').should('be.visible')
})
})
- Por fim, feche a Cypress App, abra-a de novo
npx cypress open
e execute os seguintes testes, nesta exata ordem:createProject.cy.js
, (2x) elogout.cy.js
.
Funcionalidade para validar a sessão do usuário
Se você executar novamente o teste createProject.cy.js
após ter implementado o uso da funcionalidade cy.session()
, perceberá que, se o teste de logout for executado antes, a sessão será perdida e teremos um erro.
Isso ocorre, pois, o teste de logout inválida a sessão.
- Ainda via Cypress App, execute de novo o arquivo
createProject.cy.js
- No arquivo
cypress/support/gui_commands.js
, altere o comando customizado delogin
pelo seguinte:
Cypress.Commands.add('login', (
user = Cypress.env('user_name'),
password = Cypress.env('user_password'),
{ cacheSession = true } = {},
) => {
const login = () => {
cy.visit('/users/sign_in')
cy.get("[data-qa-selector='login_field']").type(user)
cy.get("[data-qa-selector='password_field']").type(password, { log: false })
cy.get("[data-qa-selector='sign_in_button']").click()
}
const validate = () => {
cy.visit('/')
cy.location('pathname', { timeout: 1000 })
.should('not.eq', '/users/sign_in')
}
const options = {
cacheAcrossSpecs: true,
validate,
}
if (cacheSession) {
cy.session(user, login, options)
} else {
login()
}
})
-
Feche a Cypress App abra-a de novo com o comando
npx cypress open
; escolha a opção E2E Testing e inicialize o navegador Electron -
Por fim, via Cypress App, execute de novo todos os testes, quantas vezes quiser, e na ordem que quiser. Todos eles devem passar em todas execuções, porém, dependendo da ordem, um pode se beneficiar da sessão criada pelo teste anterior.
Cenário para criarção de issue via GUI
Criar um teste automatizado que exercita a funcionalidade de criação de issue via interface gráfica de usuário.
- Dentro do diretrório
cypress/e2e/gui/
, crie um arquivo chamadocreateIssue.cy.js
com os seguintes dados:
import { faker } from '@faker-js/faker'
describe('Create Issue', () => {
const issue = {
title: `issue-${faker.datatype.uuid()}`,
description: faker.random.words(3),
project: {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
}
beforeEach(() => {
cy.login()
cy.gui_createProject(issue.project)
})
it('successfully', () => {
cy.gui_createIssue(issue)
cy.get('.issue-details')
.should('contain', issue.title)
.and('contain', issue.description)
})
})
- No diretório
cypress/support/
, atualize o arquivogui_commands.js
com o commandogui_createIssue
, conforme abaixo:
Cypress.Commands.add('gui_createIssue', issue => {
cy.visit(`/${Cypress.env('user_name')}/${issue.project.name}/issues/new`)
cy.get('.qa-issuable-form-title').type(issue.title)
cy.get('.qa-issuable-form-description').type(issue.description)
cy.contains('Submit issue').click()
})
- Por fim, via Cypress App, execute o teste
createIssue.cy.js
.
Testar o cenário de criação de projeto (via API) com sucesso.
Criando um projeto via API
-
No diretório
cypress/e2e/
, crie um diretório chamadoapi/
-
Dentro do diretrório
cypress/e2e/api/
, crie um arquivo chamadocreateProject.cy.js
com os seguintes dados:
import { faker } from '@faker-js/faker'
describe('Create Project', () => {
it('successfully', () => {
const project = {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
cy.api_createProject(project)
.then(response => {
expect(response.status).to.equal(201)
expect(response.body.name).to.equal(project.name)
expect(response.body.description).to.equal(project.description)
})
})
})
- No diretório
cypress/support/
, crie um arquivo chamadoapi_commands.js
, com os seguintes dados:
import { faker } from '@faker-js/faker'
describe('Create Project', () => {
it('successfully', () => {
const project = {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
cy.api_createProject(project)
.then(response => {
expect(response.status).to.equal(201)
expect(response.body.name).to.equal(project.name)
expect(response.body.description).to.equal(project.description)
})
})
})
- Dentro do diretório
cypress/support/
, adicione ao arquivo e2e.js o import do arquivoapi_commands.js
, conforme abaixo:
import './api_commands'
import './gui_commands'
- Por fim, via Cypress App, execute o teste
cypress/e2e/api/createProject.cy.js
via o comamdonpx cypress open
.
Funcionalidade para excluír projetos criados anteriormente
Criar um mecanismo para a limpeza de projetos criados anteriomente, de forma que todos os testes que criem tal recurso possam iniciar em um estado "limpo".
- No arquivo
cypress/support/api_commands.js
, adicione os comandosapi_getAllProjects
eapi_deleteProjects
, conforme demonstrado abaixo:
Cypress.Commands.add('api_getAllProjects', () => {
cy.request({
method: 'GET',
url: '/api/v4/projects/',
headers: { Authorization: accessToken },
});
});
Cypress.Commands.add('api_deleteProjects', () => {
cy.api_getAllProjects().then(res =>
res.body.forEach(project => cy.request({
method: 'DELETE',
url: `/api/v4/projects/${project.id}`,
headers: { Authorization: accessToken },
}))
);
});
- Agora, no arquivo
cypress/e2e/api/createProject.cy.js
, adicione a função beforeEach, chamando o comando customizadocy.api_deleteProjects()
na sua função de callback, conforme abaixo:
import { faker } from '@faker-js/faker'
describe('Create issue', () => {
beforeEach(() => cy.api_deleteProjects())
it('successfully', () => {
...
})
})
-
Via Cypress App, execute novamente o teste
cypress/e2e/api/createProject.cy.js
e verifique a limpeza dos projetos criados anteriormente acontecendo -
Nos arquivos
cypress/e2e/gui/createProject.cy.js
ecypress/e2e/gui/createIssue.cy.js
, adicione também a chamada ao comando customizadocy.api_deleteProjects()
antes da chamada do comandocy.login()
, garantindo que testes de GUI também não estão a deixar "lixo" para trás -
Execute ambos os testes via Cypress App para garantir que ambos continuam funcionando.
Funcionalidade para otimizar a criação de Issue via GUI
Agora que podemos criar projetos via API, atualize o teste de criação de issue via GUI, para tal testar seja o mais otimizado possível, passando pela GUI só para o que for realmente necessário, sem a necessidade de over testing.
- altere o arquivo
cypress/e2e/gui/createIssue.cy.js
, para em vez de criar o projeto com o comando customizadocy.gui_createProject(issue.project)
, use o comandocy.api_createProject(issue.project)
- Via Cypress App, execute o arquivo
cypress/e2e/gui/createIssue.cy.js
Funcionalidade para melhorar a visualização de criação via API
- Altere o arquivo
cypress/support/e2e.js
conforme abaixo:
import 'cypress-plugin-api'
import './api_commands'
import './gui_commands'
- Altere o arquivo
cypress.config.js
conforme abaixo:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost',
env: {
hideCredentials: true,
requestMode: true,
},
},
fixturesFolder: false,
video: false,
});
- Via Cypress App, execute de novo o arquivo
cypress/e2e/api/createProject.cy.js
.
Melhorando a visualização de teste via GUI com API
funcionalidade (snapshot only mode
), para que nos testes de GUI, também tenhamos feedback visual quando chamadas de API estiverem rodando, ou quando estivermos utilizando a funcionalidade de time-traveling do Cypress.
- Adicione à função describe do arquivo
cypress/e2e/gui/createProject.cy.js
(entre a descrição do teste e a função de callback), um objeto, conforme demonstrado abaixo:
import { faker } from '@faker-js/faker'
const options = { env: { snapshotOnly: true } }
describe('Create Project', options, () => {
...
})
- Faça o mesmo para o arquivo
cypress/e2e/gui/createIssue.cy.js
, conforme demonstrado abaixo:
import { faker } from '@faker-js/faker'
const options = { env: { snapshotOnly: true } }
describe('Create Issue', options, () => {
...
})
- Via Cypress App, execute ambos os testes e utilize a funcionalidade de time travel para voltar aos passos onde as requisições de API foram executadas para ter o feedback visual de tais chamadas com a ajuda da lib cypress-plugin-api. Além disso, tenha também as snapshots da aplicação em teste, quando executando comandos via GUI.
Testa a funcionalidade de criação de issue via API
- No do diretrório
cypress/e2e/api/
, crie um arquivo chamadocreateIssue.cy.js
com os seguintes dados:
import { faker } from '@faker-js/faker'
describe('Create issue', () => {
beforeEach(() => cy.api_deleteProjects())
it('successfully', () => {
const issue = {
title: `issue-${faker.datatype.uuid()}`,
description: faker.random.words(3),
project: {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
}
cy.api_createIssue(issue)
.then(response => {
expect(response.status).to.equal(201)
expect(response.body.title).to.equal(issue.title)
expect(response.body.description).to.equal(issue.description)
})
})
})
- No diretório
cypress/support/
, atualize o arquivoapi_commands.js
com o commandoapi_createIssue
, conforme abaixo:
Cypress.Commands.add('api_createIssue', issue => {
cy.api_createProject(issue.project)
.then(response => {
cy.request({
method: 'POST',
url: `/api/v4/projects/${response.body.id}/issues`,
body: {
title: issue.title,
description: issue.description
},
headers: { Authorization: accessToken },
})
})
})
- Via Cypress App, execute o arquivo
cypress/e2e/api/createIssue.cy.js
.
Criação de label de forma otimizada
- No diretório
cypress/e2e/gui/
, crie um arquivo chamadosetLabelOnIssue.cy.js
com o seguinte conteúdo:
import { faker } from '@faker-js/faker'
const options = { env: { snapshotOnly: true } }
describe('Set label on issue', options, () => {
const issue = {
title: `issue-${faker.datatype.uuid()}`,
description: faker.random.words(3),
project: {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
}
const label = {
name: `label-${faker.random.word()}`,
color: '#ffaabb'
}
beforeEach(() => {
cy.api_deleteProjects()
cy.login()
cy.api_createIssue(issue)
.then(response => {
cy.api_createLabel(response.body.project_id, label)
cy.visit(`${Cypress.env('user_name')}/${issue.project.name}/issues/${response.body.iid}`)
})
})
it('successfully', () => {
cy.gui_setLabelOnIssue(label)
cy.get('.qa-labels-block').should('contain', label.name)
cy.get('.qa-labels-block span')
.should('have.attr', 'style', `background-color: ${label.color}; color: #333333;`)
})
})
- No diretório
cypress/support/
, atualize o arquivoapi_commands.js
conforme abaixo:
Cypress.Commands.add('api_createLabel', (projectId, label) => {
cy.request({
method: 'POST',
url: `/api/v4/projects/${projectId}/labels`,
body: {
name: label.name,
color: label.color
},
headers: { Authorization: accessToken },
})
})
- No diretório
cypress/support/
, atualize o arquivogui_commands.js
conforme abaixo:
/// <reference types="Cypress" />
Cypress.Commands.add('gui_setLabelOnIssue', label => {
cy.get('.qa-edit-link-labels').click()
cy.contains(label.name).click()
cy.get('body').click()
})
- Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando
npx cypress run --spec cypress/e2e/gui/setLabelOnIssue.cy.js
para executar o novo teste em modo headless.
Ao final da execução, deve possuir um resultado como o seguinte:
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ setLabelOnIssue.cy.js 00:05 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:05 1 1 - - -
Testar o cenário de adição de um marco a uma issue com sucesso.
- O endpoint para criação de milestones é
/api/v4/projects/:projectId/milestones
- O verbo para criação de milestones é o
POST
- O atributo que deve ser passado no
body
da requisição é otitle
(String) - Um token de autorizacão (
Authorization
) deve ser passado nosheaders
, prefixado porBearer
- No diretório
cypress/e2e/gui/
, crie um arquivo chamadosetMilestoneOnIssue.cy.js
com o seguinte conteúdo:
import { faker } from '@faker-js/faker'
const options = { env: { snapshotOnly: true } }
describe('Set milestone on issue', options, () => {
const issue = {
title: `issue-${faker.datatype.uuid()}`,
description: faker.random.words(3),
project: {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
}
const milestone = {
title: `milestone-${faker.random.word()}`
}
beforeEach(() => {
cy.api_deleteProjects()
cy.login()
cy.api_createIssue(issue)
.then(response => {
cy.api_createMilestone(response.body.project_id, milestone)
cy.visit(`${Cypress.env('user_name')}/${issue.project.name}/issues/${response.body.iid}`)
})
})
it('successfully', () => {
cy.gui_setMilestoneOnIssue(milestone)
cy.get('.block.milestone').should('contain', milestone.title)
})
})
- No diretório
cypress/support/
, atualize o arquivoapi_commands.js
conforme abaixo:
Cypress.Commands.add('api_createMilestone', (projectId, milestone) => {
cy.request({
method: 'POST',
url: `/api/v4/projects/${projectId}/milestones`,
body: { title: milestone.title },
headers: { Authorization: accessToken },
})
})
- No diretório
cypress/support/
, atualize o arquivogui_commands.js
conforme abaixo:
Cypress.Commands.add('gui_setMilestoneOnIssue', milestone => {
cy.get('.block.milestone .edit-link').click();
cy.contains(milestone.title).click();
});
Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando
npx cypress run --spec cypress/e2e/gui/setMilestoneOnIssue.cy.js
para executar o novo teste em modo headless.
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ setMilestoneOnIssue.cy.js 00:04 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:04 1 1 - - -
Executando comandos no nível do sistema operacional
- No diretório
cypress/e2e/
, crie um novo diretório chamadocli/
(Command Line Interface) - No diretório
cypress/e2e/cli/
, crie um arquivo chamadogitClone.cy.js
com o seguinte conteúdo:
import { faker } from '@faker-js/faker'
describe('git clone', () => {
const project = {
name: `project-${faker.datatype.uuid()}`,
description: faker.random.words(5)
}
beforeEach(() => {
cy.api_deleteProjects()
cy.api_createProject(project)
})
it('successfully', () => {
cy.cloneViaSSH(project)
cy.readFile(`cypress/downloads/${project.name}/README.md`)
.should('contain', `# ${project.name}`)
.and('contain', project.description)
})
})
- No diretório
cypress/support/
, crie um arquivo chamadocli_commands.js
com o seguinte conteúdo:
Cypress.Commands.add('cloneViaSSH', project => {
const domain = Cypress.config('baseUrl').replace('http://', '')
cy.exec(`cd cypress/downloads/ && git clone git@${domain}:${Cypress.env('user_name')}/${project.name}.git`)
})
- Dentro do diretório
cypress/support/
, adicione ao arquivoe2e.js
o import do arquivocli_commands.js
, conforme abaixo:
import 'cypress-plugin-api'
import './api_commands'
import './cli_commands'
import './gui_commands'
- Por fim, no terminal de linha de comando, na raiz do projeto, execute o comando
npx cypress run --spec cypress/e2e/cli/gitClone.cy.js
para executar o novo teste em modo headless.
Obs.: Na primeira execução, você será solicitada(o):
Are you sure you want to continue connecting (yes/no)?
Respondayes
e pressioneENTER
.
Obs.2: Caso o teste falhe com o erro abaixo, execute o seguinte comando: ssh-keygen -R localhost; pressione ENTER; e então, execute o teste novamente (
npx cypress run --spec cypress/e2e/cli/gitClone.cy.js
).