2017-04-13 52 views
0

我找到了SWT Browser部件的非常怪異的行爲:瀏覽器#的getText()返回空字符串

@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()返回一個空字符串。

An other question表明,它可能是因爲Browser仍在加載的頁面,但使用setText不會觸發加載(因爲HTML已經存在),以及ProgressListener不會被調用,無論是。

JavaDoc說:返回一個帶有HTML的字符串,表示當前頁面的內容。由於某種原因沒有關於返回空字符串。

如何獲取瀏覽器的文本? (我需要它爲測試條件下像上面的,所以「等待」爲Browser部件是出了問題。我不知道,將工作無論哪種方式。)

回答

1

打開後,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樣式位讓它在我的機器上運行 - 你可能不需要它。

我真的不知道爲什麼我沒有遇到HTML標記問題,如@ Baz的答案中提到的,但上面的測試通過。也許別人可以闡明一些,因爲我從來沒有使用Browser部件。另外,圍繞SWT組件編寫測試是一個巨大的痛苦,如果有什麼方法可以重構或重新設計代碼,那麼您就不必直接測試小部件(特別是當您必須創建並打開一個Shell),我會強烈建議。

+0

'Display#readAndDispatch()'使它工作,只要'Display#sleep()'沒有被調用。 (我從來沒有得到瀏覽器的內容,這就是爲什麼我從來沒有意識到結果字符串會有HTML標籤。) –

1

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

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

    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())位)?

+0

不,實際上你**不能在測試用例中擁有那個SWT事件循環。它會阻止shell直到有人點擊小X.而且你也不能有'Display#asyncExec',這甚至不是SWT測試所特有的。 –