it-source

웹 드라이버 클릭() 대 자바스크립트 클릭()

criticalcode 2023. 7. 20. 22:00
반응형

웹 드라이버 클릭() 대 자바스크립트 클릭()

이야기:

여기 StackOverflow에서 사용자가 selenium WebDriver "click" 명령을 통해 요소를 클릭할 수 없으며 스크립트를 실행하여 JavaScript 클릭으로 해결할 수 있다고 보고하는 것을 보았습니다.

파이썬의 예:

element = driver.find_element_by_id("myid")
driver.execute_script("arguments[0].click();", element)

WebDriverJS/프랙터의 예:

var elm = $("#myid");
browser.executeScript("arguments[0].click();", elm.getWebElement());

질문:

일반적인 웹 드라이버 클릭은 작동하지 않는데 "via 자바스크립트" 클릭은 작동하는 이유는 무엇입니까?이 문제가 정확히 언제 발생하고 있으며 해결 방법의 단점은 무엇입니까(있는 경우

저는 개인적으로 이 문제를 해결해야 하는 이유와 문제가 발생할 수 있는 이유를 완전히 이해하지 못한 채 이 해결 방법을 사용했습니다.

현재 승인된 답변과 달리 팬텀에 특정한 내용은 없습니다.웹드라이버가 클릭을 하도록 하는 것과 자바스크립트로 실행하는 것 사이의 차이에 관한 JS.

차이

두 방법의 본질적인 차이는 모든 브라우저에 공통적이며 매우 간단하게 설명할 수 있습니다.

  • 웹 드라이버:WebDriver는 클릭할 때 실제 사용자가 브라우저를 사용할 때 발생하는 상황을 최대한 시뮬레이션합니다."클릭 미"라고 말하는 버튼인 요소 A와 요소 B가 있다고 가정합니다.div투명하지만 치수가 있는 요소와zIndexA를 완전히 덮을 수 있도록 설정합니다.그런 다음 웹 드라이버에게 A를 클릭하라고 말합니다.웹드라이버는 클릭을 시뮬레이션하여 B가 먼저 클릭을 받도록 할 것입니다. 왜죠?B가 A를 커버하기 때문에 사용자가 A를 클릭하려고 하면 B가 먼저 이벤트를 받게 됩니다.A가 클릭 이벤트를 받을지 여부는 B가 이벤트를 처리하는 방식에 따라 달라집니다.어쨌든, 이 경우 웹 드라이버의 동작은 실제 사용자가 A를 클릭하려고 할 때와 동일합니다.

  • JavaScript:자,해서 자바스크립트를 실행한다고 .A.click()클릭 방법은 사용자가 A를 클릭하려고 할 때 실제로 발생하는 것을 재현하지 않습니다. JavaScript는 다음을 전송합니다.click이벤트는 A로 직접 전송되며 B는 이벤트를 수신하지 않습니다.

웹 드라이버 클릭이 작동하지 않을 때 자바스크립트 클릭이 작동하는 이유는 무엇입니까?

위에서 언급했듯이 WebDriver는 실제 사용자가 브라우저를 사용할 때 발생하는 상황을 최대한 시뮬레이션하려고 합니다.문제는 DOM이 사용자가 상호 작용할 수 없는 요소를 포함할 수 있다는 것이며, WebDriver는 이러한 요소를 클릭할 수 없다는 것입니다.제가 언급한 중복 사례 외에도, 이것은 보이지 않는 요소들을 클릭할 수 없습니다.스택 오버플로 질문에서 볼 수 있는 일반적인 경우는 DOM에 이미 존재하는 GUI 요소와 상호 작용하려고 하지만 다른 요소가 조작되었을 때만 표시되는 사람입니다.드롭다운 메뉴에서 이 문제가 발생할 수 있습니다. 메뉴 항목을 선택하려면 먼저 드롭다운 버튼을 클릭해야 합니다.메뉴가 표시되기 전에 누군가 메뉴 항목을 클릭하려고 하면 WebDriver가 주저하며 요소를 조작할 수 없다고 말합니다.그런 다음 사용자가 JavaScript를 사용하여 이벤트를 수행하려고 하면 이벤트가 가시성에 관계없이 요소에 직접 전달되기 때문에 작동합니다.

클릭할 때 자바스크립트를 사용해야 하는 경우?

만약 당신이 Selenium을 사용하여 애플리케이션을 테스트하고 있다면, 이 질문에 대한 저의 대답은 "거의 없다"입니다.대체로 셀레늄 테스트는 사용자가 브라우저로 수행하는 작업을 재현해야 합니다.드롭다운 메뉴의 예를 들어 보겠습니다. 테스트는 먼저 드롭다운이 나타나는 버튼을 클릭한 다음 메뉴 항목을 클릭해야 합니다.버튼이 보이지 않거나 버튼이 메뉴 항목을 표시하지 못해 GUI에 문제가 있는 경우 테스트가 실패하고 버그가 감지됩니다.JavaScript를 사용하여 클릭하면 자동 테스트를 통해 이러한 버그를 감지할 수 없습니다.

자바스크립트를 사용하는 것이 타당한 예외가 있을 수 있기 때문에 저는 "거의 절대"라고 말합니다.하지만 그들은 매우 드물 것입니다.

사이트 스크랩에 셀레늄을 사용하는 경우 사용자 동작을 복제하는 것이 중요하지 않습니다.따라서 JavaScript를 사용하여 GUI를 우회하는 것이 문제가 되지 않습니다.

드라이버에 의해 실행된 클릭은 자바스크립트 동안 가능한 한 가까운 실제 사용자의 행동을 시뮬레이션하려고 합니다.HTMLElement.click()에서는 " " " 에 대한 합니다.click요소가 상호 작용할 수 없는 경우에도 이벤트가 발생합니다.

차이점은 다음과 같습니다.

  • 운전자는 보기로 스크롤하여 요소가 보이는지 확인하고 요소가 상호 작용할 수 있는지 확인합니다.

    드라이버가 다음 오류를 발생시킵니다.

    • 클릭 좌표의 맨 위에 있는 요소가 대상 요소 또는 하위 요소가 아닌 경우
    • 요소의 크기가 양수가 아니거나 완전히 투명한 경우
    • "/" "/" "/" "/" "/")disabled이라true)
    • 비활성화된 (CSS 요소에비가경된우(CSS))pointer-events이라none)


    HTMLElement.click()요소가 비활성화된 경우에는 항상 기본 작업을 수행하거나 최대 자동으로 실패합니다.

  • 운전자는 포커스가 가능한 경우 요소에 포커스를 맞출 것으로 예상됩니다.

    HTMLElement.click()않을 것이다.

  • 드라이버는 실제 사용자와 마찬가지로 모든 이벤트(마우스 이동, 마우스다운, 마우스업, 클릭 등)를 내보내야 합니다.

    HTMLElement.click()는 (으)ㄹ 입니다.click이벤트. 페이지는 이러한 추가 이벤트에 의존할 수 있으며 이벤트가 전송되지 않으면 다르게 동작할 수 있습니다.

    다음은 운전자가 Chrome으로 클릭할 때 발생하는 이벤트입니다.

    mouseover {target:#topic, clientX:222, clientY:343, isTrusted:true, ... }
    mousemove {target:#topic, clientX:222, clientY:343, isTrusted:true, ... }
    mousedown {target:#topic, clientX:222, clientY:343, isTrusted:true, ... }
    mouseup {target:#topic, clientX:222, clientY:343, isTrusted:true, ... }
    click {target:#topic, clientX:222, clientY:343, isTrusted:true, ... }
    

    다음은 JavaScript 주입과 함께 발생하는 이벤트입니다.

    click {target:#topic, clientX:0, clientY:0, isTrusted:false, ... }
    
  • JavaScript에서 발생한 이벤트.click() 신뢰할 수 없으며 기본 작업을 실행할 수 없습니다.

    https://developer.mozilla.org/en/docs/Web/API/Event/isTrusted
    https://googlechrome.github.io/samples/event-istrusted/index.html

    일부 드라이버는 여전히 신뢰할 수 없는 이벤트를 생성하고 있습니다.입니다. 2 이후의 . 버전 2.1 JS.

  • JavaScript에서 발생한 이벤트.click() 클릭 좌표가 없습니다.

    »clientX, clientY, screenX, screenY, layerX, layerY으로 됩니다.0이 페이지는 해당 페이지에 의존할 수 있으며 다르게 작동할 수 있습니다.


JavaScript를 수 ..click()일부 데이터를 스크랩하지만 테스트 컨텍스트에는 없습니다.그것은 사용자의 행동을 시뮬레이션하지 않기 때문에 테스트의 목적을 위반합니다.따라서 드라이버에서 클릭이 실패하면 실제 사용자도 동일한 조건에서 동일한 클릭을 수행하지 못할 가능성이 높습니다.


요소가 성공할 것으로 예상될 때 드라이버가 요소를 클릭하지 못하는 이유는 무엇입니까?

  • 지연 또는 전환 효과로 인해 대상 요소를 아직 볼 수 없거나 상호 작용할 수 없습니다.

    몇 가지 예:

    https://developer.mozilla.org/fr/docs/Web (내비게이션 메뉴) http://materializecss.com/side-nav.html (내비게이션 사이드바)

    해결 방법:

    가시성, 최소 크기 또는 안정된 위치를 기다리려면 웨이터를 추가합니다.

    // wait visible
    browser.wait(ExpectedConditions.visibilityOf(elem), 5000);
    
    // wait visible and not disabled
    browser.wait(ExpectedConditions.elementToBeClickable(elem), 5000);
    
    // wait for minimum width
    browser.wait(function minimumWidth() {
        return elem.getSize().then(size => size.width > 50);
    }, 5000);
    

    성공할 때까지 클릭을 다시 시도합니다.

    browser.wait(function clickSuccessful() {
        return elem.click().then(() => true, (ex) => false);
    }, 5000);
    

    애니메이션/전환 기간과 일치하는 지연 추가:

    browser.sleep(250);
    


  • 대상 요소는 뷰로 스크롤된 후 부동 요소에 의해 가려집니다.

    드라이버는 요소를 보기로 자동 스크롤합니다.페이지에 부동/고정 요소(메뉴, 광고, 바닥글, 알림, 쿠키 정책 등)가 포함되어 있으면 해당 요소가 적용되어 더 이상 표시/상호 작용할 수 없습니다.

    예: https://twitter.com/ ?sshd=en

    해결 방법:

    스크롤 또는 부동 요소를 방지하려면 창의 크기를 더 큰 크기로 설정합니다.

    의 음를사로 합니다.Y오프셋을 누른 후 클릭합니다.

      browser.actions()
         .mouseMove(elem, {x: 0, y: -250})
         .click()
         .perform();
    

    클릭하기 전에 요소를 창의 중앙으로 스크롤합니다.

    browser.executeScript(function scrollCenter(elem) {
      var win = elem.ownerDocument.defaultView || window,
        box = elem.getBoundingClientRect(),
        dy = box.top - (win.innerHeight - box.height) / 2;
      win.scrollTo(win.pageXOffset, win.pageYOffset + dy);
    }, element);
    
    element.click();
    

    피할 수 없는 경우 부동 요소를 숨깁니다.

    browser.executeScript(function scrollCenter(elem) {
      elem.style.display = 'none';
    }, element);
    

참고: '클릭'이라고 부르는 것은 최종 사용자 클릭입니다.JS를 통해 'js click'을 클릭합니다.

일반적인 웹 드라이버 클릭은 작동하지 않는데 "via 자바스크립트" 클릭은 작동하는 이유는 무엇입니까?

다음과 같은 두 가지 경우가 발생합니다.

I. PhamtomJS를 사용하는 경우

그렇다면 이것이 가장 일반적으로 알려진 행동입니다.PhantomJS예를 들어 일부 요소는 클릭할 수 없는 경우가령<div>는 는이유 때문입니다.PhantomJS(초기 HTML + CSS -> 컴퓨팅 CSS -> 렌더링과 같은) 브라우저의 엔진을 시뮬레이션하기 위해 원래 만들어졌습니다.그러나 최종 사용자의 방식(보기, 클릭, 끌기)으로 상호 작용하는 것은 아닙니다. 그므로러.PhamtomJS최종 사용자 상호 작용을 통해 부분적으로만 지원됩니다.

JS가 작동을 클릭하는 이유는 무엇입니까?어느 클릭이든 모두 평균 클릭입니다.그것은 1개총과 2개의 방아쇠를 가진 총과 같습니다.뷰포트에서 한 명, JS에서 한 명.부터PhamtomJS브라우저의 엔진을 시뮬레이션할 때 JS 클릭은 완벽하게 작동합니다.

II. "클릭"의 이벤트 처리기가 잘못된 기간에 바인딩되었습니다.

를 들어,는 를들어는, 리우예▁a를 .<div>

  • -> 우리는 약간의 계산을 합니다.

  • ->를 -> 그런클이에를바인다니합딩에 바인딩합니다<div>.

  • -> 각도의 잘못된 코딩(예: 스코프의 사이클을 제대로 처리하지 않는 경우)도 있습니다.

우리는 같은 결과로 끝날 수도 있습니다.웹 드라이버 때문에 클릭할 수 없습니다.클릭 이벤트 핸들러가 없을 때 요소를 클릭하려고 합니다.

JS가 작동을 클릭하는 이유는 무엇입니까?Jsclick은 브라우저에 js를 직접 주입하는 것과 같습니다.두 가지 방법으로 가능합니다.

번째는 devtools 콘솔을 통해 수행됩니다(예, 웹 드라이버).JS는 devtools의 콘솔과 통신합니다.

번째는 주사입니다.<script>를 지정합니다. HTML의 경우에는 .

브라우저마다 동작이 다릅니다.그러나 이와 상관없이 이러한 방법은 버튼을 클릭하는 것보다 더 복잡합니다.클릭은 이미 존재하는 것을 사용하고 있습니다(최종 사용자 클릭). js클릭은 백도어를 통과합니다.

그리고 js의 경우 클릭은 비동기 작업으로 나타납니다.이는 '브라우저 비동기 작업CPU 작업 스케줄링'이라는 다소 복잡한 주제와 관련이 있습니다(잠시 전에 읽어보면 다시 기사를 찾을 수 없습니다).간단히 말해서, 이는 대부분 js click이 CPU의 작업 스케줄링 주기를 기다려야 하고 클릭 이벤트 바인딩 후 약간 느리게 실행되기 때문입니다. (이 경우는 때때로 클릭할 수 있지만 때로는 그렇지 않은 요소를 발견했을 때 알 수 있습니다.)

이 문제가 정확히 언제 발생하고 있으며 해결 방법의 단점은 무엇입니까(있는 경우

=> 위에서 언급한 바와 같이, 둘 다 하나의 목적을 위한 것이지만, 어느 입구를 사용하는 것에 관한 것입니다.

  • 클릭:는 기본적으로 브라우저에서 제공하는 기능을 사용합니다.
  • JS 클릭: 백도어를 통과합니다.

=> 성능은 브라우저에 의존하기 때문에 말하기 어렵습니다.하지만 일반적으로:

  • 클릭: 더 빠르다는 의미는 아니지만 CPU 실행 작업의 예약 목록에서 더 높은 위치에 서명했습니다.
  • JS click: 속도가 느리다는 의미가 아니라 CPU 작업의 일정 목록 마지막 위치에 서명한 것입니다.

=> 단점:

  • 클릭: Phamtom을 사용하는 것 외에는 단점이 없는 것 같습니다.제이에스
  • JS 클릭: 건강에 매우 나쁩니다.보기에 없는 항목을 실수로 클릭할 수 있습니다.이 기능을 사용할 때는 요소가 해당 위치에 있고 최종 사용자의 관점에서 보고 클릭할 수 있는지 확인합니다.

해결책을 찾고 있다면 추신.

  • PhantomJS 사용?대신 크롬 헤드리스를 사용하는 것을 제안하겠습니다.예, 우분투에서 헤드리스로 크롬을 설정할 수 있습니다.크롬과 똑같이 작동하지만 팬텀처럼 뷰가 없고 버그가 적습니다.제이에스
  • 가 있습니까?JS 그런데 아직도 문제가 있나요?되는 각도기 를 예되는각상사용것제을안다합니는하상태를도와 함께 하는 것을 하겠습니다.browser.wait()(자세한 내용은 이 항목을 확인하십시오.)

(짧게 하고 싶지만, 결과가 좋지 않았습니다.이론과 관련된 모든 것은 설명하기가 복잡합니다...)

좋은 설명 감사합니다, 저도 같은 문제를 겪고 있었는데 당신의 설명이 제 문제를 해결하는 데 도움이 되었습니다.

button = driver.wait.until(EC.presence_of_element_located(
    (By.XPATH, "//div[@id='pagination-element']/nav[1]/span[3]/button[1]/span[1]/i[1]")
))
driver.execute_script("arguments[0].click();", button)

enter image description here

if (theElement.Enabled)
{
    if (!theElement.Selected)
    {
      var driver = (IJavaScriptExecutor)Driver;
      driver.ExecuteScript("arguments[0].click();", theElement); //ok

      //theElement.Click();//action performed on theElement, then pops exception   
     }
 }

클릭 동작을 시뮬레이션하기 위해 JS를 "거의 사용하지 않을" 것이라는 데 동의하지 않습니다.

에 위theElement.Click()Radio(라디오) 버튼을 선택하면 위 이미지와 같이 Exception(예외)이 팝업됩니다.

후 . 버튼을 웹 가 왜 . 클릭은 라디오 단추를 선택하기 위한 것일 뿐이며 웹 드라이버를 사용하는 이유를 알 수 없습니다.Click()이 예외가 발생합니다. 이 예외가 발생한 이유를 설명할 수 있는 사람이 있습니까?

원격 테스트에는 웹 드라이버 3.141.59 및 IE 11과 selenium-server-standalone-3.141.59.jar를 사용합니다.

언급URL : https://stackoverflow.com/questions/34562061/webdriver-click-vs-javascript-click

반응형