web-dev-qa-db-ja.com

要素MyElementはポイント(x、y)ではクリックできません...他の要素がクリックを受け取ります

SeleniumベースのKatalon Studioを使用していくつかのテストを実行しようとしています。私のテストの1つでは、textarea内に記述する必要があります。問題は、次のエラーが発生することです。

...Element MyElement is not clickable at point (x, y)... Other element would receive the click...

実際、私の要素は他の歌姫の中にあり、それを隠す可能性がありますが、クリックイベントをテキストエリアにヒットさせるにはどうすればよいですか?

18
nix86

Element ... is not clickable at point (x, y). Other element would receive the click"は、さまざまな要因で発生する可能性があります。次のいずれかの手順でそれらに対処できます。

  1. JavaScriptまたはAJAX呼び出しが存在するために要素がクリックされない

Actionsクラスを使用してみてください:

WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
  1. 要素が Viewport 内にないためクリックされません

JavascriptExecutorを使用して要素をビューポート内に移動してみてください:

JavascriptExecutor jse1 = (JavascriptExecutor)driver;
jse1.executeScript("scroll(250, 0)"); // if the element is on top.
jse1.executeScript("scroll(0, 250)"); // if the element is at bottom.

または

WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement); 
  1. 要素がクリック可能になる前に、ページが更新されています。

この場合、waitを誘導します。

  1. 要素はDOMに存在しますが、クリックできません。

この場合、要素がクリック可能になるようにいくつかのExplicitWaitを追加します。

WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
  1. 要素は存在しますが、一時的なオーバーレイがあります。

この場合、ExplicitWaitExpectedConditionsオーバーレイを非表示にするには、invisibilityOfElementLocatedに設定します。

WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
  1. 要素は存在しますが、永続的なオーバーレイがあります。

JavascriptExecutorを使用して、要素のクリックを直接送信します。

WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
25
DebanjanB

私はすでにここで他のコンポーネントが重複していないことを確認していると思います(透明な広告iframeまたはDOMの他のコンポーネント=> input/textfield要素で非常に頻繁に見られるものなど)、手動で(ゆっくりと)ステップするとあなたのコード、それはスムーズに機能しています、そしてそれからajax呼び出しはこの振る舞いを引き起こすかもしれません。

Thread.sleepを回避するには、EventFiringWebDriverを使用して、ハンドルを登録してください。 (アプリケーションのtechstackに応じて、ハンドラーでAngular、JQuery、または改札のために動作する可能性があるため、さまざまな実装が必要です)(Btw:このアプローチでは、「StaleElementException」のものを何度も取り除くことができました)

参照してください:org.openqa.Selenium.support.events.EventFiringWebDriver org.openqa.Selenium.support.events.WebDriverEventListener

driveme = new ChromeDriver();
driver = new EventFiringWebDriver(driveme);
ActivityCapture handle=new ActivityCapture();
driver.register(handle);

=> ActivityCaptureはWebDriverEventListenerを実装します。改札/ dojo techstackでAjax呼び出しを処理するjavascriptExecutor

    @Override
public void beforeClickOn(WebElement arg0, WebDriver event1) {
    try {
        System.out.println("After click "+arg0.toString());
        //System.out.println("Start afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
        JavascriptExecutor executor = (JavascriptExecutor) event1;
        StringBuffer javaScript = new StringBuffer();
        javaScript.append("for (var c in Wicket.channelManager.channels) {");
        javaScript.append(" if (Wicket.channelManager.channels[c].busy) {");
        javaScript.append(" return true;");
        javaScript.append(" }");
        ;
        ;
        ;
        javaScript.append("}");
        javaScript.append("return false;");
        //Boolean result = (Boolean) executor.executeScript(javaScript.toString());
        WebDriverWait wait = new WebDriverWait(event1, 20);
        wait.until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return !(Boolean) executor.executeScript(javaScript.toString());
            }
        });
        //System.out.println("End afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
    } catch (Exception ex) {
        //ex.printStackTrace();
    }
}
3
ulrayk

Thread.Sleep()を試してください

暗黙的-Thread.Sleep()

したがって、これは実際にはSelenium WebDriverの機能ではなく、ほとんどのプログラミング言語で共通の機能です。しかし、それは問題ではありません。

Thread.Sleep()は、あなたが思っていることを正確に実行し、スレッドをスリープ状態にします。したがって、プログラムが実行されると、ほとんどの場合、そのプログラムはいくつかの自動チェックとなり、スレッド上で実行されます。したがって、Thread.Sleepを呼び出すときは、プログラムに一定期間絶対に何もせず、スリープ状態にするように指示しています。テスト対象のアプリケーションが何であるかは問題ではありません。気にしないで、チェックで昼寝をします!

残念ながら、Selenium WebDriverのGUIチェックフレームワークでThread.Sleep()のインスタンスがいくつか見られるのはごく一般的なことです。起こりがちなのは、スクリプトが失敗するか、散発的に失敗し、誰かがローカルでスクリプトを実行して、レースがあることに気づき、WedDriverが失ってしまうことです。データの量が多い場合など、アプリケーションの読み込みに時間がかかる場合があるため、修正するために、チェックが続行される前にアプリケーションが確実に読み込まれるように、仮眠を取るようWebDriverに指示します。

Thread.sleep(5000);

提供される値はミリ秒単位であるため、このコードはチェックを5秒間スリープします。

0
Pradnya Bolli

@DebanjanBが言ったように、ボタン(または別の要素)が一時的に別の要素で覆われる可能性がありますが、ボタンを覆っている要素がわからない場合でも、ボタンをクリックして待つことができます。
これを行うには、クリックアクションを使用して独自のExpectedConditionを定義できます。

public class SuccessfulClick implements ExpectedCondition<Boolean> {
    private WebElement element;

    public SuccessfulClick(WebElement element) { //WebElement element
        this.element = element;
    }

    @Override
    public Boolean apply(WebDriver driver) {
        try {
            element.click();
            return true;
        } catch (ElementClickInterceptedException | StaleElementReferenceException | NoSuchElementException e) {
            return false;
        }
    }
}

そしてこれを使用します:

WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
0
Adam Silenko