Stncil에서 select의 이벤트 점화 테스트 쓰기 변경

웹 Components 개발 라이브러리인 Stncil은 다른 자바스크립트 프레임워크와 마찬가지로 기본적으로 단원 테스트, E2E 테스트를 준비합니다.
https://stenciljs.jp/docs/testing-overview
하지만 웹 컴포니언스에서 E2E 테스트를 한다고 생각하면 섀도우돔 접속에 자주 빠져들지만, 이번에는 select를 바꿔 활동하는 방법에 고민이 있으니 공유해보자.

테스트 구성 요소


구성 요소는 웹 Component 내select DOM의 다음 형식입니다.여기onChange를 E2E 테스트에서 실행하고 myChange 이벤트에 불을 붙입니다.구성 요소 이름은 my-select입니다.
@Component({
  tag: 'my-select',
  styleUrl: 'my-select.scss',
  shadow: true,
})
export class MySelect {
  ...
  private onChange = event => {
    this.myChange.emit({ value: event.target.value });
  };
  render() {
    return (
      <Host>
        <select onChange={this.onChange}>
          {options.map(option => (
            <option value={option.value}>{option.label}</option>
          ))}
        </select>
      </Host>
    );
  }
}

테스트 코드


테스트를 쓸 때 반드시 주의해야 할 것은 Puppeteerselect 방법은 ShadowDOM에서 사용할 수 없다는 것이다.
https://github.com/puppeteer/puppeteer/issues/4171
따라서 PuppeteerevaluateHandle를 이용하여 방문 창 대상,document 대상과 동시에DOM을 진행한다.
그럼 시험은 다음과 같습니다.
describe('my-select', () => {
  it('change', async () => {
    const page = await newE2EPage();
    await page.setContent(`<my-select></my-select>`,);
    await page.waitForChanges();
    
    const change = await page.spyOnEvent('myChange');

    await page.evaluateHandle(() => {
      return new Promise(resolve => {
        // my-select DOMを取得
        const element = document.querySelector('my-select');

	// myChangeイベントが発火したら非同期処理を解決
        element.addEventListener('myChange', event => {
          resolve();
        });
	
	// my-select DOM内の select DOMを取得
        const select: HTMLSelectElement = element.shadowRoot.querySelector(
          'select',
        );
	// select DOMにイベントをdispatch
        select.dispatchEvent(
          new Event('change', { bubbles: true, composed: true }),
        );
      });
    });

    await page.waitForChanges();
    expect(change).toHaveReceivedEvent();
  });
});

page.spyOnEvent('myChange')에서 사건myChange의 발화 여부를 검사하는 모듈 대상을 만들고 변수change에 저장한다.이후 활동에 불이 나면 expect(change).toHaveReceivedEvent() 테스트를 통과한다.(※ 이벤트에 불이 붙지 않았을 때toHaveReceivedEvent, 테스트에 실패했습니다.)Puppeteerselect방법을 사용할 수 없기 때문에dispatchEvent강제점화onChange사건을 사용합니다.이렇게 되면 addEventListener가 감시하는myChange에서 불이 나고evaluateHandle 내 프로미스가 해결해 후속 처리를 하게 된다.
섀도돔 디자인에 조금 시간이 걸렸지만 간단하게 테스트를 마쳤다.여기서 발화toHaveReceivedEventDetail 방법만 확인되면 활동 내용도 테스트할 수 있다.
그럼 안녕히 계세요.

좋은 웹페이지 즐겨찾기