Selenium webdriver在浏览器中新添加的对象上从isDisplayed()返回false,然后返回InvalidElementStateException

Mor*_*ork 4 java selenium webdriver

我在我的脚本中有一个方法,我在循环中使用它来确定对象是否在尝试与之交互之前是否已启用并显示,如下所示: -

public boolean isElementPresent(By myObject, individualThreadSession threadSesh) {
        try{
            if(threadSesh.driver.findElement(myObject).isEnabled() && threadSesh.driver.findElement(myObject).isDisplayed()) {
                return true;
            } else {
                return false;
            }
        } 
        catch (NoSuchElementException e){
            return(false);
        } 
    }
Run Code Online (Sandbox Code Playgroud)

myobject部分从读取的内容传入: - isElementPresent(By.xpath(IDString),threadSesh)

所以我传递相关的By(通过运行时指定的数据确定)

到目前为止,这对我来说已经很好了很长一段时间.我点击一个链接后,我试图点击插入页面的对象,问题是Selenium threadSesh.driver.findElement(myObject).isDisplayed()在屏幕上清晰可见对象的部分返回false .

我可以手动与这个对象进行精细交互,如果我使用IDE记录它,它似乎工作得很好......任何人都知道如何解决这个问题?或者强迫Selenium认为对象是显示的?

当我没有添加对象时,我正在处理的区域的HTML如下: -

<td class="activecomment">
    <div data-bind="template: { name: 'commentControlPriorities', data: $data }" style="position: relative">
        <div style="margin-right: 10px" data-bind="with: $data.LatestComment, flash: $data.LatestComment">
            <div data-bind="style: { display: editMode() ? 'none' : 'block' }" style="display: block;">
                <!-- Highlighted comment -->
                <div class="comment labelgrey highlightcomment" data-bind="css: { highlightcomment: $parent.CommentSupportsApproving() && !CommentApproved() }">
                    <div style="word-wrap: break-word" data-bind="text: CommentView">No comment</div>
                    <div style="margin-top: 5px;">
                        <!-- ko if: $parent.isEnabled("Edit") -->
                        <a class="btn btn-small btn-info" data-bind="click: toggleEditMode, clickBubble: false" title="Leave Comment" href="#">
                        <img class="MYIcon" src="/Content/images/edit-icon.png"/>
                        </a>
                        <!-- ko if: $parent.CommentSupportsApproving() && CommentView() != "No comment" -->
                        <!-- /ko -->
                        <!-- /ko -->
                        <span class="lightergrey pull-right">
                            <span data-bind="cutSurname: User"/>
                            <span data-bind="relativeDateFormat: CommentDateView"/>
                        </span>
                    </div>
                </div>
            </div>
            <!-- Editable comment - temporarily hidden -->
            <!-- ko if: $parent.isEnabled("Edit") -->
            <div data-bind="template: { name: 'commentEditControl', data: $data }">
                <div class="labelgrey" style="background-color: rgb(255, 255, 255); padding: 1px; margin: 5px 0px; border: 1px solid rgb(110, 121, 131); display: none;" data-bind="style: { display: editMode() ? 'block' : 'none' }">
                    <textarea id="editcommenttext_0bf0e2db-0662-4b13-8a3c-1840cca79ba6" class="latestComment limitedText editCommentTextArea" data-bind="value: CommentUpdate, valueUpdate: 'afterkeydown', attr: {id: 'editcommenttext_'+$parentContext.$parent.Id()}" style="font-size: 12px; line-height: 18px; width: 100%; background-color: #FFF; border: 0px; resize: none; padding: 0px; margin: 0px; min-height: 54px"/>
                    <span class="validationMessage" style="display: none;"/>
                    <div style="background-color: #6E7983; padding: 5px;">
                        <a id="editcommentsave_0bf0e2db-0662-4b13-8a3c-1840cca79ba6" class="btn btn-small btn-info" data-bind="event: { click: function (data, parent) { saveComment($parentContext.$parent) } }, attr: {id: 'editcommentsave_'+$parentContext.$parent.Id()}" style="margin-right: 7px;" title="Save Comment" href="#">                 Save             </a>
                        <a id="cancelComment" class="cancel" data-bind="click: cancelComment" href="#">Cancel</a>
                        <div style="float: right; font-size: 10px; color: #FFF;">
                            <span class="limitedTextCharactersCount" data-bind="text: RemainingCharacterCount">240</span>
                             characters             
                        </div>
                    </div>
                </div>
            </div>
            <!-- /ko -->
        </div>
    </div>
</td>
Run Code Online (Sandbox Code Playgroud)

一旦你点击了对象 <a class="btn btn-small btn-info" data-bind="click: toggleEditMode, clickBubble: false" title="Leave Comment" href="#"> <img class="MYIcon" src="/Content/images/edit-icon.png"/> </a>

它改为:

<td class="activecomment">
    <div data-bind="template: { name: 'commentControlPriorities', data: $data }" style="position: relative">
        <div style="margin-right: 10px" data-bind="with: $data.LatestComment, flash: $data.LatestComment">
            <div data-bind="style: { display: editMode() ? 'none' : 'block' }" style="display: none;">
                <!-- Highlighted comment -->
                <div class="comment labelgrey highlightcomment" data-bind="css: { highlightcomment: $parent.CommentSupportsApproving() && !CommentApproved() }">
                    <div style="word-wrap: break-word" data-bind="text: CommentView">No comment</div>
                    <div style="margin-top: 5px;">
                        <!-- ko if: $parent.isEnabled("Edit") -->
                        <a class="btn btn-small btn-info" data-bind="click: toggleEditMode, clickBubble: false" title="Leave Comment" href="#">
                        <img class="MYIcon" src="/Content/images/edit-icon.png"/>
                        </a>
                        <!-- ko if: $parent.CommentSupportsApproving() && CommentView() != "No comment" -->
                        <!-- /ko -->
                        <!-- /ko -->
                        <span class="lightergrey pull-right">
                            <span data-bind="cutSurname: User"/>
                            <span data-bind="relativeDateFormat: CommentDateView"/>
                        </span>
                    </div>
                </div>
            </div>
            <!-- Editable comment - temporarily hidden -->
            <!-- ko if: $parent.isEnabled("Edit") -->
            <div data-bind="template: { name: 'commentEditControl', data: $data }">
                <div class="labelgrey" style="background-color: rgb(255, 255, 255); padding: 1px; margin: 5px 0px; border: 1px solid rgb(110, 121, 131); display: block;" data-bind="style: { display: editMode() ? 'block' : 'none' }">
                    <textarea id="editcommenttext_0bf0e2db-0662-4b13-8a3c-1840cca79ba6" class="latestComment limitedText editCommentTextArea" data-bind="value: CommentUpdate, valueUpdate: 'afterkeydown', attr: {id: 'editcommenttext_'+$parentContext.$parent.Id()}" style="font-size: 12px; line-height: 18px; width: 100%; background-color: #FFF; border: 0px; resize: none; padding: 0px; margin: 0px; min-height: 54px"/>
                    <span class="validationMessage" style="display: none;"/>
                    <div style="background-color: #6E7983; padding: 5px;">
                        <a id="editcommentsave_0bf0e2db-0662-4b13-8a3c-1840cca79ba6" class="btn btn-small btn-info" data-bind="event: { click: function (data, parent) { saveComment($parentContext.$parent) } }, attr: {id: 'editcommentsave_'+$parentContext.$parent.Id()}" style="margin-right: 7px;" title="Save Comment" href="#">                 Save             </a>
                        <a id="cancelComment" class="cancel" data-bind="click: cancelComment" href="#">Cancel</a>
                        <div style="float: right; font-size: 10px; color: #FFF;">
                            <span class="limitedTextCharactersCount" data-bind="text: RemainingCharacterCount">240</span>
                             characters             
                        </div>
                    </div>
                </div>
            </div>
            <!-- /ko -->
        </div>
    </div>
</td>
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用XPATH .//textarea[contains(@id,'editcommenttext')],我已经在firepath中进行了变换,目标只是我想要的textarea,但没有成功.有什么建议?是否有什么问题的HTML我可以让开发人员改变,以使selenium在这里返回true?

似乎如果我删除isDisplayed支票然后继续我的代码我然后得到一个错误说明.InvalidElementStateException: Element must not be hidden, disabled or read-only当我尝试键入单元格等.

我也尝试让开发人员给它一个ID,这样我就可以通过ID找到对象并没有区别.

所以关于这个对象的东西没有启用/可见,但是我看不清楚它是什么(它在屏幕上清晰可见等等(当我正在调试时,我正在给它足够的时间来加载页面,然后继续.

谢谢

我认为我知道问题是什么! 当我使用Selenium IDE记录进程时它附加[3]到xpath,结果是当我认为这个对象是在运行时添加的时候实际上是在所有行上添加然后只是隐藏了,所以现在我需要添加我的对象中的某些内容检查以运行与XPATH/ID匹配的所有对象,然后使用它首先遇到的启用和可见的任何一个....我将确认是否是这种情况.

Mor*_*ork 7

对此的答案令人沮丧地简单.我使用的XPATH不够具体,当我认为它只返回一个时返回多个对象,然后将Seleniums注意到数组中第一个不可见的(因为它正确报告).

一旦我改变了我的方法以返回匹配对象的数组并简单地循环直到我找到一个既启用又显示使用罗伯特是我母亲的兄弟.

狡猾的XPATH问题来自于我在firepath中检查了XPATH(在firefox中),这正确地突出了我想要的对象但是 selenium实际上可以实际上是同一对象的倍数(尽管页面源不显示多于1个对象)直到我使用firefox Selenium插件来记录我的动作时才向我突出显示.

因此,这里学到的教训是,如果没有首先检查Selenium IDE,它似乎无法正常工作,则不信任通过firepath 100%生成的XPATH ...!