프로젝트의 필요에 따라 테스트 중에 웹페이지 요소의 스크린샷이 정상적으로 보이는지 확인해야 합니다. 이전에방법을 소개하는 글을 썼습니다 먼저 WebDriver를 사용하여 전체 화면 스크린샷을 찍은 다음 대상 요소(DOM 요소)의 위치에 따라 스크린샷을 자르고 필요한 위치를 유지했습니다.
내가 뭔가를 알아내기 전까지 해당 코드는 잘 작동하고 있었습니다: iframe. iframe(일반 프레임은 동일하지만 현재 프레임은 덜 일반적입니다. 여기서는 iframe만 예시로 사용됨)의 콘텐츠는 독립적인 웹 페이지로 간주되며 Window 개체도 상위 웹 페이지와 분리됩니다. WebDriver의 WebElement.getLocation() 메소드는 이 WebElement와 그것이 위치한 Window 사이의 위치 관계만 반환할 수 있습니다. 구현에는 문제가 없지만 전체 화면 스크린샷에는 iframe의 콘텐츠뿐만 아니라 콘텐츠에는 상위 페이지의 콘텐츠도 포함될 수 있으므로 자를 때 스크린샷에서 대상 요소의 위치를 알아야 합니다. 그렇다면 굴삭기 기술이 가장 뛰어난 회사는 어디일까요? 스크린샷을 기준으로 요소의 위치를 계산하는 방법은 무엇입니까?
이 문제는 별도의 카테고리에서 논의해야 합니다. 이유는 Chrome과 Firefox의 스크린샷 동작이 다르기 때문입니다. Chrome의 스크린샷은 현재 표시되는(뷰포트) 웹페이지 콘텐츠입니다. 예를 들어 웹페이지의 실제 크기가 Chrome 창 크기를 초과하는 경우 Chrome의 스크린샷 위치에 따라 창에 표시되는 콘텐츠가 달라집니다. 표시된 내용. 따라서 현재 표시되는 콘텐츠를 기준으로 대상 요소의 위치를 계산해야 합니다. Firefox는 현재 창 크기에 관계없이 전체 웹 페이지의 콘텐츠를 캡처할 수 있는 방법을 사용합니다. 따라서 Firefox의 경우 요소의 절대 위치(Absolute Position)를 계산해야 합니다.
요소의 위치를 얻으려면 Element.getBoundingClientRect() 메소드를 사용해야 합니다. 이 메서드는 이 요소가 위치한 Windows의 현재 표시되는 콘텐츠를 기준으로 이 요소의 위치를 반환하며, 위쪽, 왼쪽, 오른쪽, 아래쪽의 네 가지 값으로 표시됩니다. 클리핑 크기는 계산 없이 요소 자체의 길이와 너비에서 얻을 수 있습니다. 최상위 창을 기준으로 대상 요소의 위치를 계산하려면 상위 창의 위쪽과 왼쪽만 순서대로 추가하면 됩니다. 코드는 다음과 같습니다.
function calcViewportLocation(element) { var currentWindow = window; var rect = element.getBoundingClientRect(); // 元素的位置 var top = rect.top; var left = rect.left; while (currentWindow.frameElement != null) { // 处理父级 Window element = currentWindow.frameElement; currentWindow = currentWindow.parent; rect = element.getBoundingClientRect(); if (rect.top > 0) { top += rect.top; } if (rect.left > 0) { left += rect.left; } } return [Math.round(top), Math.round(left)]; }
위 코드는 Chrome에서 작동하지만 Firefox에서는 요소의 절대 위치도 계산해야 합니다. 여기에는 Window.pageXOffset이 필요합니다. pageXOffset 또는 scrollX는 현재 창의 가로 스크롤 막대의 스크롤 위치를 나타냅니다. 이 값을 위 왼쪽에 추가하면 대상 요소의 가로 절대 위치를 얻을 수 있습니다. 물론 iframe을 특별하게 처리할 수도 있습니다.
function calcAbsolutLocation(element) { var top = 0; var left = 0; var currentWindow = window; while (element != null) { rect = element.getBoundingClientRect(); var pageYOffset = currentWindow.pageYOffset; var pageXOffset = currentWindow.pageXOffset; if (typeof pageYOffset === 'undefined') { // IE8 currentDocument = currentWindow.document; var bodyElement = (currentDocument.documentElement || currentDocument.body.parentNode || currentDocument.body); pageYOffset = bodyElement.scrollTop; pageXOffset = bodyElement.scrollLeft; } top += rect.top + pageYOffset; left += rect.left + pageXOffset; element = currentWindow.frameElement; currentWindow = currentWindow.parent; if (element != null) { style = window.getComputedStyle(element); top += parseInt(style.borderTopWidth, 10); left += parseInt(style.borderLeftWidth, 10); } } return [Math.round(top), Math.round(left)]; }
IE8은 pageXOffset과 scrollX를 지원하지 않기 때문에 IE8에서는 특별한 처리가 필요합니다. 즉, 코드에서 "IE8"이라고 표시된 부분입니다. 이 두 가지 Javascript 코드를 이전 기사의 WebElement.getLocation()으로 바꾸면 iframe의 특정 요소에 대한 스크린샷을 찍을 수 있습니다.