>  기사  >  백엔드 개발  >  Go-DOM - Go로 작성된 헤드리스 브라우저입니다.

Go-DOM - Go로 작성된 헤드리스 브라우저입니다.

Linda Hamilton
Linda Hamilton원래의
2024-11-07 18:28:02800검색

Go-DOM - A headless browser written in Go.

할 일이 너무 적으면 가끔 말도 안되는 아이디어가 나올 때도 있는데, 이번에는; v8 엔진을 내장하여 완전한 DOM 구현과 JavaScript 지원을 갖춘 헤드리스 브라우저를 Go에 작성하는 것이었습니다.

모든 작업은 HTMX 애플리케이션 작성으로 시작되었으며 이를 테스트해야 했기 때문에 헤드리스 브라우저의 순수 Go 구현이 있는지 궁금했습니다.

'헤드리스 브라우저로 이동'을 검색하면 헤드리스 브라우저 자동화, 즉 헤드리스 모드에서 Firefox의 Chrome과 같은 실제 브라우저를 사용하는 것에 대한 검색 결과만 나옵니다.

하지만 순수 Go에는 아무것도 없습니다.

그래서 하나 만들기 시작했습니다.

Go에 헤드리스 브라우저가 필요한 이유는 무엇입니까?

헤드리스 브라우저를 작성하는 것은 결코 실제 브라우저처럼 작동하지 않기 때문에 어리석게 보일 수도 있습니다. 따라서 지원하기로 결정한 모든 브라우저에서 애플리케이션이 올바르게 작동하는지 실제로 확인할 수는 없습니다. 또한 작동이 중지되었을 때 애플리케이션의 스크린샷과 같은 멋진 기능을 얻을 수도 없습니다.

그럼 왜요?

속도가 필요합니다!

효과적인 TDD 루프에서 작업하려면 테스트가 빨라야 합니다. 느린 테스트 실행으로 인해 TDD가 방해를 받고 빠른 피드백 루프가 제공하는 효율성 이점을 잃게 됩니다.

이러한 유형의 확인을 위해 브라우저 자동화를 사용하면 심각한 오버헤드가 발생하며 이러한 테스트는 일반적으로 코드가 작성된 후에 작성됩니다. 따라서 더 이상 올바른 구현을 작성하는 데 도움이 되지 않습니다. 그러나 이후에는 유지 관리 부담이 줄어듭니다. 유료 고객보다 가끔 버그를 발견하는 경우가 있습니다.

목표는 TDD 프로세스를 지원하는 도구를 만드는 것입니다. 사용하려면 프로세스 내에서 실행되어야 합니다.

Go로 작성해야 합니다.

덜 불안정한 테스트

DOM을 내부 프로세스로 사용하면 DOM 위에 더 나은 래퍼를 작성할 수 있습니다. 이는 테스트 라이브러리가 JavaScript에서 수행하는 것처럼 테스트에 덜 불규칙한 인터페이스를 제공하는 데 도움이 될 수 있습니다.

CSS 클래스 이름, 요소 ID 또는 DOM 구조에 의존하는 대신 이와 같이 사용자 중심 언어로 테스트를 작성합니다.

'이메일'이라는 라벨이 있는 텍스트 상자에 'me@example.com'을 입력하세요.

또는 가상의 코드에서

testing.GetElement(Query{
  role: "textbox",
  // The accessibility "name" of a textbox _is_ the label
  name: "Email",
}).type("me@example.com")

이 테스트는 라벨이

이는 동작 확인과 UI 변경을 분리합니다. 하지만 실행 "이메일"이라는 텍스트가 액세스 가능한 방식으로 입력 필드와 연결되도록 강제합니다. 이는 테스트를 사용자가 페이지와 상호작용하는 방식과 결합합니다. 페이지를 사용하기 위해 스크린 리더에 의존하는 사람들도 포함됩니다.

이는 TDD의 가장 중요한 측면을 달성합니다. 구체적인 행동과 결합된 테스트를 작성합니다.1

비록 프로세스 외부 브라우저에 대해 동일한 테스트를 작성하는 것이 기술적으로 가능할 수도 있지만; 이러한 유형의 도우미에 가장 필요할 수 있는 DOM의 무작위 액세스 유형에는 네이티브 코드의 이점이 필수적입니다.

예: 자바스크립트

테스트 유형을 예시하기 위해 JavaScript의 유사한 예시를 사용하겠습니다. HTMX를 사용하는 애플리케이션이기도 합니다. 테스트에서는 인증이 필요한 페이지를 요청하는 일반적인 로그인 흐름을 확인합니다.

여기서는 모든 설정과 도우미 코드를 하나의 테스트 함수로 묶어서 좀 깁니다.

testing.GetElement(Query{
  role: "textbox",
  // The accessibility "name" of a textbox _is_ the label
  name: "Email",
}).type("me@example.com")

간단히 말하면 테스트는 다음을 수행합니다.

  1. 성공적인 응답을 시뮬레이션하여 인증 기능을 스터브합니다.
  2. 인증이 필요한 페이지 요청
  3. 브라우저가 로그인 페이지로 리디렉션되고 브라우저 URL이 업데이트되는지 확인하세요. 2
  4. 양식에 예상 값을 작성하고 제출하세요.
  5. 브라우저가 원래 요청한 페이지로 리디렉션되고 스텁된 사용자에 대한 정보가 표시되는지 확인하세요.

테스트는 내부적으로 HTTP 서버를 시작합니다. 이는 테스트 프로세스에서 실행되기 때문에 비즈니스 로직의 조롱 및 스텁이 가능합니다. 테스트에서는 jsdom을 사용하여 HTTP 서버와 통신합니다. 이는 HTML 응답을 DOM으로 구문 분석할 뿐만 아니라 초기화된 샌드박스에서 클라이언트 측 스크립트를 실행합니다. 창을 전역 범위로 사용합니다.3

이를 통해 응답 내용의 유효성을 검사하는 것만으로는 충분하지 않은 HTTP 계층의 테스트 작성이 가능해집니다. 이 경우; 의도한 대로 응답이 HTMX에 의해 처리됩니다.

그러나 일부 HTMX 이벤트를 기다리는 것 외에는 일찍(또는 너무 늦게) 진행되지 않도록 테스트는 실제로 HTMX에 관심이 없습니다. 실제로 클래식 리디렉션을 사용하여 양식에서 HTMX를 제거해도 테스트는 여전히 통과됩니다.

(HTMX