【问题标题】:How to detect the value of a TextArea has changed?如何检测 TextArea 的值发生了变化?
【发布时间】:2015-03-19 13:49:44
【问题描述】:

我正在测试一个网络聊天应用程序。每次与我聊天的用户发送消息时,它都会附加到文本区域,就像任何聊天解决方案一样。我想检测新消息何时到达并获取其内容(文本)。

这类似于拦截给定元素的 javascript onChange 事件。是否可以使用 Selenium WebDriver 做到这一点?

我有兴趣在任何支持此功能的浏览器上进行测试。我对在所有可能的浏览器上测试这种行为不感兴趣。

其目的是开发类似于聊天机器人的东西,每次对方发送消息时都会发回消息。例如:

Remote user sends: Hello!
Selenium detects that and sends back: Your last message was "Hello!".

我无法更改聊天应用代码。

是否可以在不合并文本区域的情况下做到这一点?我的意图是监听事件,但我找不到类似的东西,而且我被告知 Selenium WebDriver 不支持它。

【问题讨论】:

    标签: java selenium-webdriver


    【解决方案1】:

    好吧,回答你的问题 - “有可能吗?” - 绝对是的! 如何 ? - 嗯,这真的取决于聊天应用程序及其界面的自动化程度。

    以这个简单的聊天应用程序(它就像一个聊天机器人)为例 - http://www.unionplatform.com/?page_id=2247 (我在示例代码中使用了它的直接 URL)。

    检查下面的代码,我只是检查<span>标签的更新值并循环它5次以读取用户输入并回复相同的消息+循环计数(以区分消息) .

    您可以采用类似的方法,但正如我所提到的,这完全取决于聊天应用程序。

    代码如下:

    public class WhiteBoard {
    
    public WebDriver driver;
    public String css_chat_text = "div#chatPane>span";
    public String css_input_msg = "input#outgoing";
    public String css_send_button = "input[value='Send']";
    public String last_message = "";
    
    public static void main(String[] args) throws Exception {
    
        WhiteBoard objTest = new WhiteBoard();
        objTest.chatBot();
    
    }
    
    public void chatBot() throws Exception{
    
        driver = new FirefoxDriver();
        driver.navigate().to("http://unionplatform.com/samples/orbitermicro/UnionChatPart1/chat.html");
    
        List<WebElement> objChats = driver.findElements(By.cssSelector(css_chat_text));
        if(objChats.size() > 0){
            System.out.println("Starting chattter...");
            String status;
            //loop until chat ready
            do{
                Thread.sleep(3000);
                objChats = driver.findElements(By.cssSelector(css_chat_text));
    
                status = objChats.get(objChats.size()-1).getText().toString();
                System.out.println(status);
    
            }while(!status.contains("Chat ready!"));
    
            Thread.sleep(3000);
            //start chatting...
            sendMessage("Hello...");
    
            for(int i=0; i<5; i++) {
                objChats = driver.findElements(By.cssSelector(css_chat_text));
                last_message = objChats.get(objChats.size()-1).getText().toString().trim();
                sendMessage("LastMsg:" + last_message + "#" +i);
                Thread.sleep(5000);
            }
        }
        else{
            System.out.println("Chat not found...");
        }
    }
    
    
    public void sendMessage(String message){
    
        //start chatting...
        List<WebElement> objInput = driver.findElements(By.cssSelector(css_input_msg));
        if(objInput.size() > 0){
            objInput.get(0).sendKeys(message);
            System.out.println("Sent message..." + message);
            List<WebElement> btnSend = driver.findElements(By.cssSelector(css_send_button));
            btnSend.get(0).click();
        }
    }
    
    }
    

    睡眠只是粗略地等待聊天框更新,理想情况下我会继续检查&lt;span&gt;计数并在增加后继续。

    上面代码的控制台输出看起来像 - https://gist.github.com/anonymous/f1eef7198648d95f1d01

    还有一个关于 SO 的有趣问题可能会有所帮助 - How to test chat web app

    【讨论】:

    • 很好的例子!它真的很有用。据我了解,您正在汇集 css_chat_text 元素。这就是我试图避免的,但这似乎是不可能的(根据 dming 的回答)。非常感谢。
    【解决方案2】:

    我认为 Selenium WebDriver 没有内置对监听事件的支持,因此最好的选择可能是轮询您正在寻找的元素的变化。

    类似:

    private void pollForTextChange()
    {
        WebElement textArea = this.driver.findElement(By.tagName("textarea"));
    
        int maxPollTime = 60;
        String lastText = textArea.getText();
        String currentText = textArea.getText();
        for (int i=0; i<maxPollTime; i++)
        {
            Thread.sleep(maxPollTime * 1000);
            currentText = textArea.getText();
            if (!currentText.equals(lastText))
            {
                // Change detected, perform desired actions here
    
                // Assuming it's a chat app and the new text should always contain existing text
                // and you want to get the new content sent
                String newContent = "";
                if (currentText.contains(lastText))
                {
                    newContent = currentText.replace(lastText, "").trim();
                    // Found new input, performed desired actions here
                }
            }
    
            lastText = currentText;
        }
    }
    

    【讨论】:

    • 当然可以。然而,这正是我试图避免的。我将尝试找到一种替代方法。如果找不到,那就走这条路。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    相关资源
    最近更新 更多