Modern Web Uygulamaları için End-to-End Test Otomasyonu
Cypress, modern web uygulamaları için geliştirilmiş bir end-to-end (E2E) test framework'üdür. JavaScript/TypeScript ile yazılır ve gerçek tarayıcıda çalışır.
Cypress Node.js gerektirir. Node.js resmi sitesinden indirin ve kurun.
{
"scripts": {
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"cypress:run:chrome": "cypress run --browser chrome",
"cypress:run:firefox": "cypress run --browser firefox"
}
}
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
viewportWidth: 1280,
viewportHeight: 720,
defaultCommandTimeout: 10000,
requestTimeout: 10000,
responseTimeout: 10000,
video: true,
screenshotOnRunFailure: true,
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
})
describe('İlk Test Suitesi', () => {
it('Google ana sayfasını ziyaret eder', () => {
cy.visit('https://www.google.com')
cy.title().should('contain', 'Google')
cy.get('[name="q"]').should('be.visible')
})
it('Google aramasi yapar', () => {
cy.visit('https://www.google.com')
cy.get('[name="q"]')
.type('Cypress testing{enter}')
cy.url().should('include', 'search')
cy.get('#search').should('be.visible')
})
})
npm run cypress:open
npm run cypress:run
describe('Element Seçiciler', () => {
beforeEach(() => {
cy.visit('https://example.com')
})
it('Çeşitli seçiciler kullanır', () => {
// ID ile seçim
cy.get('#my-id')
// Class ile seçim
cy.get('.my-class')
// Attribute ile seçim
cy.get('[data-cy="submit-button"]')
// Text içeriği ile seçim
cy.contains('Giriş Yap')
// CSS seçici
cy.get('button.primary')
// İlk/son element
cy.get('li').first()
cy.get('li').last()
// Index ile seçim
cy.get('li').eq(2)
})
})
describe('Form Testleri', () => {
it('Login formu doldurur ve gönderir', () => {
cy.visit('/login')
// Input alanlarını doldur
cy.get('[data-cy="username"]').type('testuser')
cy.get('[data-cy="password"]').type('password123')
// Checkbox işaretle
cy.get('[data-cy="remember-me"]').check()
// Select dropdown
cy.get('[data-cy="country"]').select('Turkey')
// Radio button seç
cy.get('[data-cy="gender"][value="male"]').check()
// Form gönder
cy.get('[data-cy="submit"]').click()
// Sonucu kontrol et
cy.url().should('include', '/dashboard')
cy.contains('Hoş geldiniz').should('be.visible')
})
})
describe('Etkileşim Testleri', () => {
it('Çeşitli etkileşimler gerçekleştirir', () => {
cy.visit('/interactive-page')
// Hover efekti
cy.get('.menu-item').trigger('mouseover')
// Double click
cy.get('.double-click-area').dblclick()
// Sağ tık
cy.get('.context-menu').rightclick()
// Scroll işlemi
cy.get('.long-content').scrollTo('bottom')
cy.scrollTo(0, 500)
// File upload
cy.get('input[type="file"]').attachFile('example.pdf')
})
})
describe('API Testleri', () => {
const baseUrl = 'https://jsonplaceholder.typicode.com'
it('GET request testi', () => {
cy.request({
method: 'GET',
url: `${baseUrl}/posts/1`
}).then((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.have.property('id', 1)
expect(response.body).to.have.property('title')
expect(response.body.userId).to.be.a('number')
})
})
it('POST request testi', () => {
const newPost = {
title: 'Test Başlık',
body: 'Test içerik',
userId: 1
}
cy.request({
method: 'POST',
url: `${baseUrl}/posts`,
body: newPost,
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
expect(response.status).to.eq(201)
expect(response.body.title).to.eq(newPost.title)
expect(response.body.body).to.eq(newPost.body)
expect(response.body.id).to.be.a('number')
})
})
})
describe('Authentication API Testleri', () => {
let authToken
before(() => {
// Login yaparak token al
cy.request({
method: 'POST',
url: '/api/login',
body: {
username: 'testuser',
password: 'password123'
}
}).then((response) => {
authToken = response.body.token
})
})
it('Protected endpoint test', () => {
cy.request({
method: 'GET',
url: '/api/protected-data',
headers: {
'Authorization': `Bearer ${authToken}`
}
}).then((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.have.property('data')
})
})
})
<!-- İyi -->
<button data-cy="submit-button">Gönder</button>
<!-- Kötü -->
<button class="btn btn-primary submit-btn">Gönder</button>
// İyi
cy.get('[data-cy="submit-button"]').click()
// Kötü
cy.get('.btn.btn-primary.submit-btn').click()
Cypress.Commands.add('login', (username, password) => {
cy.visit('/login')
cy.get('[data-cy="username"]').type(username)
cy.get('[data-cy="password"]').type(password)
cy.get('[data-cy="login-button"]').click()
})
// Kullanım
cy.login('testuser', 'password123')
{
"validUser": {
"username": "testuser",
"password": "password123",
"email": "test@example.com"
},
"invalidUser": {
"username": "wronguser",
"password": "wrongpass"
}
}
describe('Login Testleri', () => {
beforeEach(() => {
cy.fixture('users').as('userData')
})
it('Geçerli kullanıcı ile giriş yapar', function() {
cy.visit('/login')
cy.get('[data-cy="username"]').type(this.userData.validUser.username)
cy.get('[data-cy="password"]').type(this.userData.validUser.password)
cy.get('[data-cy="login-button"]').click()
})
})
function()
yerine () =>
kullanmayın) çünkü this
context'i gereklidir.
// Debug için duraklatma
cy.debug()
// Console'a log yazdırma
cy.log('Bu bir log mesajıdır')
// Pause komutu
cy.pause()
// Screenshot alma
cy.screenshot()
cy.screenshot('login-page')
module.exports = defineConfig({
e2e: {
env: {
apiUrl: 'https://api.example.com',
username: 'testuser'
}
}
})
// Test dosyasında kullanım
cy.visit(Cypress.env('apiUrl'))
cy.get('[data-cy="username"]').type(Cypress.env('username'))
describe('Test Suite', () => {
beforeEach(() => {
// Her testten önce verileri temizle
cy.task('cleanDatabase')
cy.clearCookies()
cy.clearLocalStorage()
})
afterEach(() => {
// Her testten sonra screenshot al (hata durumunda)
cy.screenshot()
})
})
{
"scripts": {
"cypress:parallel": "cypress-parallel -s cypress:run -t 2 -d cypress/e2e"
}
}
describe('Beklemeler ve Doğrulamalar', () => {
it('Çeşitli bekleme ve doğrulamalar yapar', () => {
cy.visit('/dynamic-content')
// Element görünür olana kadar bekle
cy.get('.loading').should('be.visible')
cy.get('.content').should('be.visible')
cy.get('.loading').should('not.exist')
// Text kontrolü
cy.get('h1').should('contain.text', 'Başlık')
cy.get('h1').should('have.text', 'Tam Başlık Metni')
// Attribute kontrolü
cy.get('input').should('have.attr', 'placeholder', 'Email giriniz')
cy.get('button').should('have.class', 'btn-primary')
// CSS property kontrolü
cy.get('.box').should('have.css', 'color', 'rgb(255, 0, 0)')
// URL kontrolü
cy.url().should('eq', 'https://example.com/page')
cy.location('pathname').should('eq', '/page')
// Custom timeout
cy.get('.slow-loading', { timeout: 15000 }).should('be.visible')
})
})
Bu rehberle ilgili sorularınız için:
🎉 Cypress ile test yazmaya başlamak için tüm bilgilere sahipsiniz!
Bu rehberi takip ederek modern web uygulamaları için güvenilir testler yazabilir ve uygulamalarınızın kalitesini artırabilirsiniz.