簡體   English   中英

selenium chrome 驅動程序的 getText() 方法有時會返回一個空字符串

[英]getText() method of selenium chrome driver sometimes returns an empty string

我有一個奇怪的情況,即 selenium chrome 驅動程序getText()方法(java)為某些元素返回一個空字符串,即使它為具有相同xpath其他元素返回一個非空字符串。 這是頁面的一部分。

<div __gwt_cell="cell-gwt-uid-223" style="outline-style:none;">
<div>Text_1</div>
<div>Text_2</div>
<div>Text_3</div>
<div>Text_4</div>
<div>Text_5</div>
<div>Text_6</div>
</div>

對於每個內部標簽,我可以獲得getTagName()getLocation()isEnabled()isDisplayed()有效返回值。 但是,getText() 會為某些 div 返回一個空字符串。

此外,我注意到如果我使用 mac chrome 驅動程序,它始終是getText()返回空字符串的“Text_5”。 如果我使用 windows chrome 驅動程序,它始終是getText()返回空字符串的“Text_2”。 如果我使用 firefox 驅動程序, getText()會從所有 div 返回預期的文本。

有沒有其他人遇到過這種困難?

在我的代碼中,我使用了這樣的東西......

ArrayList<WebElement> list = (ArrayList<WebElement>) driver.findElements(By.xpath(“my xPath here”));
for (WebElement e: list) System.out.println(e.getText());

如下所示,這是我正在使用的實際xPath 上面的頁面片段處理最后兩個 div。

//*[@class='gwt-DialogBox']//tr[contains(@class,'data-grid-table-row')]//td[contains(@class,'lms-assignment-selection-wizard-cell')]/div/div

更新: textContent屬性是一個更好的選擇,大多數瀏覽器都支持。 這篇博文詳細解釋了這些差異:innerText vs. textContent

作為替代方案, innerText屬性將返回存在於 DOM 中的元素的文本內容。

element.getAttribute("innerText")

當元素不是真正隱藏而是在視口之外時, isDisplayed()方法有時會被絆倒; getText()為這樣的元素返回一個空字符串。

您還可以通過使用 javascript 滾動到該元素將元素帶入視口,如下所示:

((JavaScriptExecutor)driver).executeScript("arguments[0].scrollIntoView(true);", element);

然后getText()應該返回正確的值。

可以在這個 SO 問題中找到有關isDisplayed()方法的詳細信息:

Selenium WebDriver 的 isDisplayed() 方法是如何工作的

WebElement.getAttribute("value") 應該可以幫助你!!

這不是解決方案,所以我不知道它是否屬於答案,但是評論太長並且包含鏈接,所以我將其作為答案。

我也有這個問題。 在做了一些挖掘之后,似乎在嘗試獲取屏幕上不可見的元素的文本時出現了問題。(正如上面@Faiz 評論的那樣。)如果元素沒有滾動到,或者如果你向下滾動,元素靠近文檔頂部,滾動后不再可見。 我看到您有一個 FindElements() 調用來獲取元素列表。 至少有些可能是不可見的; 您可以通過嘗試boolean b = webElement.isDisplayed();來檢查這一點boolean b = webElement.isDisplayed(); 在列表中的每個元素上並檢查結果。 (請參閱 此處對這個問題進行了很長時間的討論,該問題已有一年之久,仍然沒有解決方案。)

顯然,這是一個深思熟慮的設計決定(請參閱此處); 不可見元素上的 gettext 應該返回空。 為什么他們如此堅定,我不知道。 已經提出了各種解決方法,包括在獲取其文本或滾動到該元素之前單擊該元素。 (有關后者的示例代碼,請參見上面的鏈接。)我無法保證這些,因為我還沒有嘗試過,但他們只是試圖使元素可見,以便文本可用。 不確定這對您的應用程序有多實用; 這不是給我的。 出於某種原因,FirefoxDriver 沒有這個問題,所以這就是我使用的。

很抱歉,我不能給你一個更好的答案——也許如果你在問題頁面上提交錯誤報告,他們會看到很多人發現它是一個錯誤而不是一個功能,他們會改變功能。

祝你好運! bsg

編輯

有關可能的解決方法,請參閱 此問題 如果 isDisplayed 返回 true,您將無法完全按照給定的方式使用它,但是如果您知道哪個元素導致了問題,或者文本通常不是空白並且您可以設置“如果字符串為空”條件來捕獲當它發生時,你仍然可以嘗試它。 不幸的是,它並不適用於所有人。

新更新我剛剛嘗試了下面給出的答案,它對我有用。 所以謝謝你,法茲!

for (int count=0;count<=sizeofdd;count++)
{       
   String GetInnerHTML=getddvalue.get(count).getAttribute("innerHTML");
}

其中, 1. getddvalue 是 WebElement 2. sizeofdd 是 getddvalue 的大小

element.getAttribute("innerText")為我工作,當getText()返回空時。

我最近遇到了類似的問題。

我必須檢查滾動框中是否存在菜單選項卡“LIFE EVENTS”。 問題是有很多菜單選項卡,您需要向下滾動才能看到其余的菜單選項卡。 所以我最初的解決方案適用於可見的菜單選項卡,但不適用於那些看不見的選項卡。

我使用下面的 xpath 將 selenium 指向整個滾動框的父元素。

@FindBy(xpath = "//div[contains(@class, 'menu-tree')]")
protected WebElement menuTree;

然后我創建了一個我可以遞增的 WebElements 列表。 如果菜單選項卡可見,該解決方案有效,並返回 true。 但是如果菜單選項卡不在視線范圍內,則返回 false

public boolean menuTabPresent(String theMenuTab) {
    List<WebElement> menuTabs = new ArrayList<WebElement>();
    menuTabs = menuTree.findElements(By.xpath("//i/following-sibling::span"));

    for(WebElement e: menuTabs) {
        System.out.println(e.getText());
        if(e.getText().contains(theMenuTab)) {
            return true;
        }
    }
    return false;
}

我找到了解決這個問題的2 個解決方案,它們都同樣有效。

    for(WebElement e: menuTabs) {
        scrollElementIntoView(e); //Solution 1
        System.out.println(e.getAttribute("textContent")); //Solution 2
        if(e.getAttribute("textContent").contains(theMenuTab)) {
            return true;
        }
    }
    return false;

解決方案 1 調用下面的方法。 這會導致在 selenium 運行時滾動框物理向下移動。

protected void scrollElementIntoView(WebElement element) {
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true)", element);
}

解決方案 2 獲取您指向的屬性的文本內容(即使對於當前不可見的菜單選項卡)。 因此正確地完成了 .getText() 在這種情況下無法完成的工作。

如果你不關心 isDisplayed 或滾動位置,你也可以寫

String text = ((JavaScriptExecutor)driver).executeScript("return $(arguments[0]).text();", element);

或者沒有 jquery

String text = ((JavaScriptExecutor)driver).executeScript("return arguments[0].innerText;", element);

getText()我也有一個問題,我解決了這個問題:

WebElement errMsg;
errMsg = driver.findElement(By.xpath("//div[@id='mbr-login-error']"));
WebElement parent = driver.findElement(By.xpath("//form[@id='mbr-login-form']"));
List<WebElement> children = parent.findElements(By.tagName("div")); 
System.out.println("Size is: "+children.size());
//((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView(true);", children);
for(int i = 0;i<children.size();i++)
{
    System.out.println(i + " " + children.get(i).getText());
}
int indexErr = children.indexOf(errMsg);
System.out.println("index " + indexErr);
Assert.assertEquals(expected, children.get(indexErr).getText());

以上解決方案都不適合我。

為我工作:

添加大於 0 的字符串長度作為 xpath 的謂詞:

String text = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[string-length(text()) > 0]"))).getText();

我的是python ,但核心邏輯是相似的:

  • webElement.text
  • webElement.get_attribute("innerText")
  • webElement.get_attribute("textContent")

完整代碼:

def getText(curElement):
    """
    Get Selenium element text

    Args:
        curElement (WebElement): selenium web element
    Returns:
        str
    Raises:
    """
    # # for debug
    # elementHtml = curElement.get_attribute("innerHTML")
    # print("elementHtml=%s" % elementHtml)

    elementText = curElement.text # sometime NOT work

    if not elementText:
        elementText = curElement.get_attribute("innerText")

    if not elementText:
        elementText = curElement.get_attribute("textContent")

    # print("elementText=%s" % elementText)
    return elementText

調用它:

curTitle = getText(h2AElement)

希望對你有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM