Develop Note by J.S.

[Cypress] Custom Command Test 본문

FrontEnd/Cypress

[Cypress] Custom Command Test

js-web 2023. 7. 18. 10:31
반응형

Cypress의 Custom Commend를 활용한 Login, Logout Test 입니다. 

1. Commend 등록

cypress/support/commonds.ts 파일과 cypress/support/index.d.ts 에 사용할 Custom Command를 정의합니다.

// cypress/support/commands.ts file

// 요소 가져오기
Cypress.Commands.add('dataCy', (selector) => {
    return cy.get(`[data-cy=${selector}]`);
});

// 요소 접근 후 클릭
Cypress.Commands.add('actionClick', (selector) => {
    return cy.get(`[data-cy=${selector}]`).click();
});

// 요소 접근 후 disabled 확인
Cypress.Commands.add('disabled', (selector) => {
    return cy.get(`[data-cy=${selector}]`).should('be.disabled');
});

// 요소 접근 후 enabled 확인
Cypress.Commands.add('enabled', (selector) => {
    return cy.get(`[data-cy=${selector}]`).should('not.be.disabled');
});

// 요소 접근 후 text 포함 여부 확인
Cypress.Commands.add('isContains', (selector, text) => {
    return cy.get(`[data-cy=${selector}]`).contains(`${text}`);
});

// 요소 접근 후 해당 요소에 typing
Cypress.Commands.add('insertText', (selector, text) => {
    return cy.get(`[data-cy=${selector}]`).type(`${text}`);
});

// 요소 접근 후 입력값 clear
Cypress.Commands.add('clearData', (selector) => {
    return cy.get(`[data-cy=${selector}]`).clear();
});

 

// cypress/support/index.d.ts

declare namespace Cypress {
    interface Chainable {
        dataCy(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
        disabled(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
        enabled(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
        isContains(dataTestAttribute: string, text: string): Chainable<JQuery<HTMLElement>>;
        insertText(dataTestAttribute: string, type: string): Chainable<JQuery<HTMLElement>>;
        clearData(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
        actionClick(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
    }
}

 

2. Attribute 추가

cy.get 으로 접근 할 요소에 'data-cy' (custom attribute name)와 key 값을 추가합니다. 

// ex. data-cy="cyName" 추가
<div class="recaptcha-area" data-cy="cyName">
</div>

3. Test Code 작성

Login Page에서 테스트 할 login.cy.ts 파일과 로그인 후 Main Page에서 테스트 할 main.cy.ts로 나누어 작성하였습니다.

// cypress/e2e/login.cy.ts
describe('Login page', () => {
    beforeEach(() => {
    	cy.visit('/');
    });
    it('URL 접근 시 로그인 페이지를 확인한다.', () => {
        cy.isContains('headerTitle', 'Login');
        //cy.get('[data-cy=headerTitle]').contains('Login');
    });

    it('잘못된 이메일을 입력할 시 버튼 disable을 확인한다.', () => {
        cy.clearData('email');
        //cy.get('[data-cy=email]').clear();

        cy.insertText('email', 'test@naver');
        //cy.get('[data-cy=email]').type('test@naver');

        cy.disabled('loginButton');
        //cy.get('[data-cy=loginButton]').should('be.disabled');
    });

    it('비밀번호 오류 시 reCaptcha 노출을 확인한다..', () => {
        cy.clearData('email');
        //cy.get('[data-cy=email]').clear();

        cy.insertText('email', 'test@naver.com');
        //cy.get('[data-cy=email]').type('test@naver.com');

        cy.clearData('password');
        //cy.get('[data-cy=password]').clear();

        cy.insertText('password', '1234');
        //cy.get('[data-cy=password]').type('1234');

        cy.actionClick('loginButton');
        //cy.get('[data-cy=loginButton]').click();

        cy.enabled('reCaptcha');
        //cy.get('[data-cy=reCaptcha]').should(be.enabled);
    });

    it('로그인 버튼 클릭 시 Main Page로 전환됨을 확인한다.', () => {
        cy.clearData('email');
        //cy.get('[data-cy=email]').clear();

        cy.insertText('email', 'test@naver.com');
        //cy.get('[data-cy=email]').type('test@naver.com');

        cy.clearData('password');
        //cy.get('[data-cy=password]').clear();

        cy.insertText('password', '1q2w3e4r');
        //cy.get('[data-cy=password]').type('1q2w3e4r');

        cy.actionClick('loginButton');
        //cy.get('[data-cy=loginButton]').click();

        cy.isContains('headerTitle', 'Main');
        //cy.get('[data-cy=headerTitle]').contains('Main');
    });
});
// cypress/e2e/main.cy.ts
describe('Main page', () => {
	// before(()=>{})  : before은 테스트 실행 전 1회만 수행 됨
    beforeEach(() => { // beforeEach는 각 테스트 코드가 실행되기 전에 매번 수행 됨
        cy.visit('/');

        cy.clearData('email');
        //cy.get('[data-cy=email]').clear();

        cy.insertText('email', 'test@naver.com');
        //cy.get('[data-cy=email]').type('test@naver.com');

        cy.clearData('password');
        //cy.get('[data-cy=password]').clear();

        cy.insertText('password', '1q2w3e4r');
        //cy.get('[data-cy=password]').type('1q2w3e4r');

        cy.actionClick('loginButton');
        //cy.get('[data-cy=loginButton]').click();
    });

    it('로그아웃 버튼 클릭 시 Login Page로 전환됨을 확인한다.', () => {
        cy.actionClick('expandButton');
        //cy.get('[data-cy=expandButton]').click();

        cy.actionClick('logoutButton');
        //cy.get('[data-cy=logoutButton]').click();

        cy.isContains('headerTitle', 'Login');
        //cy.get('[data-cy=headerTitle]').contains('Login');
    });
});

4. 테스트 결과

1) cypress open

2) cypress run

반응형

'FrontEnd > Cypress' 카테고리의 다른 글

[Cypress] Store 연동(pinia)  (0) 2023.07.25
[Cypress] TDD vs BDD  (0) 2023.07.24
[Cypress] Cypress + MSW  (0) 2023.07.17
[Cypress] Api Test  (0) 2023.07.12
[Cypress] Cypress Methods & Assertions정리  (0) 2023.07.12