-
Notifications
You must be signed in to change notification settings - Fork 59
Hybridity And View Management
QtWebDriver can drive UIs based on:
- QWebViews.
- QWidgets views.
- QDeclarativeViews.
- QGraphicsWebViews.
- Hybrids of the these. (QWeb/DeclarativeViews embedded in QWidgets, etc...)
When navigating to an URL WebDriver will do the following checks:
- If the current view is compatible with the requested content then use it.
- Otherwise apply the view transition policy to the current view.
- Then create a view of a type that is compatible with the requested content.
Views can be created either at session startup or when transitioning between content.
The class of the View to create at session startup can be specified:
- On client side, use the Selenium
browserClass
capability to specificy the class to create:
capabilities.setCapability("browserClass", "MyWebView");
driver = new RemoteWebDriver(ip:port, capabilities);
etc...
- On server side, register the class to create, or one of its subclasses must have been registered to WebDriver.
e.g:
//Configure web support
webdriver::ViewCreator* webCreator = new webdriver::QWebViewCreator();
//Register custom web view subclass
webCreator->RegisterViewClass<QWebViewExt>("MyWebView");
When creating a session with such capabilities QtWebDriver will try to create an instance of MyWebView
or one of its subclasses.
When QtWebDriver detects the requested content (as in WebDriver.get(URL content)
) cannot be displayed by the current view (as in WebDriver.getWindowHandle()
), then it will:
- apply the configured transition policy
e.g: to close all previous views
webdriver::ViewTransitionManager::SetURLTransitionAction(new webdriver::URLTransitionAction_CloseOldView());
- attempt to create a view that can manage the requested content:
QtWebDriver wd = new QtWebKitDriver(host, caps);
// This will trigger creation of a QWebView
wd.get("http://html5test.com/");
...
// This will trigger creation of a QDeclarativeView
wd.get("http://qmltest.com/foo.qml");
...
// This will trigger creation of a MyWidgetClass
wd.get("qtwidget://MyWidgetClass");
//etc...
See Headers.h for an example to configure QtWebDriver.
See Doxygen
HTML | Widget | QML | |
---|---|---|---|
Compatible views | QWebViews | QWidgets | QDeclarativeViews |
Supported URL scheme |
|
qtwidget://<widget class> | any qml file URL |
UI source | <!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html> |
<MainWindow name="WD_native"> <QLineEdit id="InputText"/> <QPushButton id="PushButton"/> <QPushButton id="PushButton2"/> <QWidget id="Frame"> <QPushButton id="FrameButton"/> <QPushButton id="FrameButton2"/> </QWidget> </MainWindow> |
<QDeclarativeView> <Rectangle id="theRectangle"/> <Rectangle id="theRectangle2"/> </QDeclarativeView> |
Locator strategies |
|
|
|
Javascript Injection | Y, as specified by W3C spec | N/A | Partial, as permitted in QML |
Hybrid UI are made of different type of content. e.g: html inside widget, QML inside widget, etc...
In the hybrid UI above (a WebView and andother menu widgets), WebDriver will consider there are 2 document roots (cf http://www.w3.org/TR/webdriver/#defining-window-and-frame):
The "source" for this type of UI would look like this:
<!- Main window, a window handle ->
<MainWindow name="WD_native" elementId=":qtw:5bc59415">
<QLineEdit id="InputText" elementId=":qtw:7c5c413e"/>
<QPushButton id="PushButton" elementId=":qtw:002e6aa8"/>
<QPushButton id="PushButton2" elementId=":qtw:68a743bf"/>
<QWidget id="Frame" elementId=":qtw:155c2ecd">
<QPushButton id="FrameButton" elementId=":qtw:5067ef6e"/>
<QPushButton id="FrameButton2" elementId=":qtw:3e34e310"/>
</QWidget>
<!- Embedded web window, another window handle ->
<QWebView elementId=":qtw:5135c3c1"/>
</MainWindow>
Handles to the windows roots will be returned by org.openqa.selenium.WebDriver.getWindowHandles()
.
In this case it will return:
- 1 handle for the main window
- 1 handle for the web view
Each window can be navigated to with WebDriver.switchTo().window(handle)
, then WebDriver will work relatively to the focused window.
e.g:
public class Test extends TestCase {
QtWebKitDriver driver;
String webDriverUrl = "http://192.168.0.2:9517";
@Override
protected void setUp() throws Exception {
super.setUp();
DesiredCapabilities capability = new DesiredCapabilities();
//Start WebDriver by reusing existing widget UI
capability.setCapability("browserStartWindow", "*");
driver = new RemoteWebDriver(new URL(webDriverUrl), capability);
}
public void test() throws InterruptedException, IOException {
//First the current window is the browser window (i.e: widget root)
String rootWindowHandle = driver.getWindowHandle();
System.out.println("Browser window handle is " + rootWindowHandle);
//Assert there are 2 windows, one for the widget root, one for the web documents in each tab
Set<String> windowHandles = driver.getWindowHandles();
assertTrue(windowHandles.size() == 2);
//Select http
String httpHandle = selectWindow("http");
assertNotNull(httpHandle);
//Then navigate html as usual
WebElement elt = driver.findElement(By.xpath("//html/body"));
}
private String selectWindow(String protocol) {
Set<String> windowHandles = driver.getWindowHandles();
for (Iterator<String> iterator = windowHandles.iterator(); iterator.hasNext();) {
String w = iterator.next();
driver.switchTo().window(w);
if (driver.getCurrentUrl().startsWith(protocol))
return w;
}
return null;
}
}
Qt4 | Qt5 | |
---|---|---|
QWidget | Y | Y |
QWebView | Y | Y |
QDeclarativeView | Y | Y |
QDeclarativeWebView | Y | N (see note 1) |
QGraphicsWebView | Y | Y |
Home | Build And Run | Releases | Features
Copyright © 1992-2016 Cisco and/or its affiliates