Browser#getText() returns 空字符串

Browser#getText() returns empty string

我发现 SWT Browser 小部件的一个非常奇怪的行为:

@Test
public void test() throws Exception {
    Shell shell = new Shell();
    Browser browser = new Browser(shell, SWT.NONE);
    browser.setText("Hello World!");
    shell.open();

    Assert.assertEquals("Hello World!", browser.getText());
}

此测试失败,因为Browser#getText() returns 一个空字符串。

An other question 建议可能是因为 Browser 仍在加载页面,但使用 setText 不会触发加载(因为 HTML 已经存在),并且 ProgressListener 也永远不会被调用。

JavaDoc 说:Returns 带有 HTML 的字符串表示当前页面的内容。 由于某种原因返回空字符串没有任何意义.

如何获取浏览器的文本? (我需要它用于像上面这样的测试用例,所以 "waiting" 用于 Browser 小部件是不可能的。我不确定这是否可行。)

下面的代码打印 Browser 的文本:

public static void main(String[] args)
{
    final Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());
    shell.setText("Whosebug");

    Browser browser = new Browser(shell, SWT.NONE);
    browser.setText("THIS IS A TEST");

    shell.pack();
    shell.open();

    display.asyncExec(() -> System.out.println(browser.getText()));

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

请注意,您返回的文本与您设置的文本不同。浏览器添加 <html><head><body> 标签:

<html><head></head><body>THIS IS A TEST</body></html>

我以前从未为 SWT 编写过测试,但是您的代码中不应该仍然有 SWT 事件循环(while(!shell.isDisposed()) 位)吗?

打开 Shell 后,您需要调用 Display.readAndDispatch() 以确保处理所有排队的事件(包括设置 Browser 上的文本):

@Test
public void test() throws Exception {
    final Shell shell = new Shell();
    final Browser browser = new Browser(shell, SWT.WEBKIT);
    browser.setText("Hello World!");
    shell.open();
    while (shell.getDisplay().readAndDispatch()) {
        // Loop here in case there is more than one event in the queue
        // Also, it may be advised to call Display.sleep() here as well
    }
    Assert.assertEquals("Hello World!", browser.getText());
}

请注意,我必须将 SWT.WEBKIT 样式位添加到我机器上的 运行 - 你可能不需要它。

老实说,我不确定为什么我没有 运行 解决@Baz 回答中提到的 HTML 标签的问题,但上述测试通过了。也许其他人可以阐明这一点,因为我从来没有使用过 Browser 小部件。

顺便说一句,围绕 SWT 组件编写测试是一件非常痛苦的事情,如果有任何方法可以重构或重新设计您的代码,那么您就不必直接测试小部件(尤其是当您必须创建和打开一个 Shell),我会强烈建议它。