/**************************************************************************** * Copyright 2008-2011 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Initial Contributors: * Håkan Råberg * Manish Chakravarty * Pavan K S ***************************************************************************/ package com.thoughtworks.krypton.driver.web.selenium; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.swt.SWT; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.sun.org.apache.xml.internal.serialize.OutputFormat; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; import com.thoughtworks.krypton.driver.web.browser.BrowserFamily; import com.thoughtworks.krypton.driver.web.browser.BrowserSession; import com.thoughtworks.krypton.driver.web.browser.BrowserSessionFactory; import com.thoughtworks.krypton.driver.web.browser.Decorators; import com.thoughtworks.krypton.driver.web.browser.locator.DomLocatorStrategy; import com.thoughtworks.krypton.driver.web.browser.locator.ElementNotFoundException; import com.thoughtworks.krypton.driver.web.browser.locator.XPathLocatorStrategy; import com.thoughtworks.krypton.driver.web.browser.wait.AjaxWaitStrategy; import com.thoughtworks.krypton.driver.web.browser.wait.DocumentReadyWaitStrategy; import com.thoughtworks.krypton.driver.web.browser.wait.SetTimeoutWaitStrategy; import com.thoughtworks.krypton.driver.web.selenium.dialog.AlertHandler; import com.thoughtworks.krypton.driver.web.selenium.dialog.ConfirmationHandler; import com.thoughtworks.krypton.driver.web.selenium.dialog.DialogHandler; import com.thoughtworks.krypton.driver.web.selenium.dialog.PromptHandler; import com.thoughtworks.krypton.driver.web.selenium.locator.AltLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.ClassLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.CssSelectorLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.IdLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.IdentifierLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.LinkLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.locator.NameLocatorStrategy; import com.thoughtworks.krypton.driver.web.selenium.stringmatch.ExactMatcher; import com.thoughtworks.krypton.driver.web.selenium.stringmatch.GlobMatcher; import com.thoughtworks.krypton.driver.web.selenium.stringmatch.RegexpMatcher; import com.thoughtworks.krypton.driver.web.selenium.stringmatch.StringMatcher; import com.thoughtworks.krypton.driver.web.user.User; import com.thoughtworks.krypton.driver.web.user.UserFactory; import com.thoughtworks.selenium.Selenium; import static java.util.Arrays.*; public class TwistSelenium implements Selenium { private static final Pattern COOKIE_PATH_PATTERN = Pattern.compile("path=([\\w|/|-]+)"); private static final Pattern COOKIE_MAX_AGE_PATTERN = Pattern.compile("max_age=(-?\\d+)"); private BrowserSession session; private String title; private List<StringMatcher> stringMatchers = new ArrayList<StringMatcher>(); private String browserUrl; public void setBrowserUrl(String browserUrl) { this.browserUrl = browserUrl; } private int speed; private AlertHandler alertHandler; private ConfirmationHandler confirmationHandler; private PromptHandler promptHandler; private AjaxWaitStrategy ajaxWaitStrategy; private DocumentReadyWaitStrategy documentReadyWaitStrategy; private User user; public TwistSelenium(String browserURL) { this(browserURL, new BrowserSessionFactory().create()); } public TwistSelenium(String browserUrl, final BrowserSession session) { this.browserUrl = browserUrl; this.session = session; } private void init() { User plainUser = new UserFactory().createUser(session.getBrowser().getShell()); user = Decorators.wrapWithLogging(User.class, plainUser); addWaitStrategies(session); addLocatorStrategies(session); addStringMatchers(); addDialogHandlers(session); } private void addDialogHandlers(BrowserSession session) { alertHandler = new AlertHandler(session); confirmationHandler = new ConfirmationHandler(session); promptHandler = new PromptHandler(session); } public void addLocationStrategy(String strategyName, String functionDefinition) { throw new UnsupportedOperationException(); } public void addSelection(String locator, String optionLocator) { doSelection(locator, optionLocator, true, true); } public void allowNativeXpath(String allow) { } public void altKeyDown() { throw new UnsupportedOperationException(); } public void altKeyUp() { throw new UnsupportedOperationException(); } public void answerOnNextPrompt(String answer) { promptHandler.answer(answer); } public void assignId(String locator, String identifier) { session.execute(session.domExpression(locate(locator)) + ".setAttribute('id', '" + identifier + "')"); waitForIdle(); } public void attachFile(String fieldLocator, String fileLocator) { throw new UnsupportedOperationException(); } public void captureEntirePageScreenshot(String filename) { throw new UnsupportedOperationException(); } public void captureScreenshot(String filename) { throw new UnsupportedOperationException(); } public void check(String locator) { if (!isChecked(locator)) { click(locator); } } public void chooseCancelOnNextConfirmation() { confirmationHandler.cancel(); } public void chooseOkOnNextConfirmation() { confirmationHandler.ok(); } public void click(String locator) { click(locate(locator)); } public void clickAt(String locator, String coordString) { Rectangle rectangle = session.boundingRectangle(locate(locator)); String[] coordinates = coordString.split(","); user.click(rectangle.x + Integer.parseInt(coordinates[0]), rectangle.y + Integer.parseInt(coordinates[1])); waitForIdle(); } public void close() { session.getBrowser().getShell().setVisible(false); } public void contextMenu(String locator) { throw new UnsupportedOperationException(); } public void contextMenuAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void controlKeyDown() { throw new UnsupportedOperationException(); } public void controlKeyUp() { throw new UnsupportedOperationException(); } public void createCookie(String nameValuePair, String optionsString) { String[] nameAndValue = nameValuePair.split("="); internalSetCookie(nameAndValue[0], nameAndValue[1], optionsString); } public void deleteAllVisibleCookies() { try { for (String cookie : getCookie().split(";")) { String[] nameAndValue = cookie.split("="); deleteCookie(URLDecoder.decode(nameAndValue[0], "UTF-8"), ""); } } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public void deleteCookie(String name, String optionsString) { internalSetCookie(name, "", "max_age=-1, " + optionsString); } private void internalSetCookie(String name, String value, String optionsString) { String cookie = name.trim() + "=" + value; Matcher matcher = COOKIE_MAX_AGE_PATTERN.matcher(optionsString); if (matcher.find()) { int days = Integer.parseInt(matcher.group(1)); Date date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); cookie += "; expires=' + new Date(" + date.getTime() + ").toUTCString() + '"; } matcher = COOKIE_PATH_PATTERN.matcher(optionsString); String path = ""; if (matcher.find()) { path = matcher.group(1); } else if (optionsString.startsWith("/")) { path = optionsString; } else { try { path = new URL(getLocation()).getPath(); if (path.contains("/")) { path = path.substring(0, path.lastIndexOf("/") + 1); } } catch (MalformedURLException e) { throw new RuntimeException(e); } } cookie += "; path=" + path.trim(); session.execute(session.getDocumentExpression() + ".cookie = '" + cookie + "'"); } public void doubleClick(String locator) { Point center = session.center(locate(locator)); user.doubleClick(center.x, center.y); waitForIdle(); } public void doubleClickAt(String locator, String coordString) { Rectangle rectangle = session.boundingRectangle(locate(locator)); String[] coordinates = coordString.split(","); user.doubleClick(rectangle.x + Integer.parseInt(coordinates[0]), rectangle.y + Integer.parseInt(coordinates[1])); waitForIdle(); } public void dragAndDrop(String locator, String movementsString) { Point source = session.center(locate(locator)); String[] movement = movementsString.split(","); user.dragAndDrop(source.x, source.y, source.x + Integer.parseInt(movement[0]), source.y + Integer.parseInt(movement[1])); waitForIdle(); } public void dragAndDropToObject(String locatorOfObjectToBeDragged, String locatorOfDragDestinationObject) { Point source = session.center(locate(locatorOfObjectToBeDragged)); Point destination = session.center(locate(locatorOfDragDestinationObject)); user.dragAndDrop(source.x, source.y, destination.x, destination.y); waitForIdle(); } public void dragdrop(String locator, String movementsString) { dragAndDrop(locator, movementsString); } public void fireEvent(String locator, String eventName) { fireEvent(locate(locator), eventName); } private void fireEvent(Element element, String eventName) { session.fireEvent(element, eventName); waitForIdle(); } public void focus(String locator) { session.execute(session.domExpression(locate(locator)) + ".focus()"); } public String getAlert() { if (!alertHandler.isDialogPresent()) { throw new IllegalStateException("No alert present"); } return alertHandler.getMessage(); } public String[] getAllButtons() { throw new UnsupportedOperationException(); } public String[] getAllFields() { throw new UnsupportedOperationException(); } public String[] getAllLinks() { throw new UnsupportedOperationException(); } public String[] getAllWindowIds() { throw new UnsupportedOperationException(); } public String[] getAllWindowNames() { throw new UnsupportedOperationException(); } public String[] getAllWindowTitles() { throw new UnsupportedOperationException(); } public String getAttribute(String attributeLocator) { int indexOfAt = attributeLocator.lastIndexOf("@"); String locator = attributeLocator.substring(0, indexOfAt); if (new XPathLocatorStrategy().canLocate(locator) && locator.endsWith("/")) { locator = locator.substring(0, locator.length() - 1); } String attribute = attributeLocator.substring(indexOfAt + 1); Element element = locate(locator); return element.getAttribute(attribute); } public String[] getAttributeFromAllWindows(String attributeName) { throw new UnsupportedOperationException(); } public String getBodyText() { return getText("document.body"); } public String getConfirmation() { if (!confirmationHandler.isDialogPresent()) { throw new IllegalStateException("No confirmation present"); } return confirmationHandler.getMessage(); } public String getCookie() { return session.evaluate(session.getDocumentExpression() + ".cookie"); } public String getCookieByName(String name) { try { for (String cookie : getCookie().split(";")) { String[] nameAndValue = cookie.split("="); if (name.equals(URLDecoder.decode(nameAndValue[0], "UTF-8"))) { return URLDecoder.decode(nameAndValue[1], "UTF-8"); } } throw new IllegalArgumentException("Cookie '" + name + "' not found."); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public Number getCursorPosition(String locator) { Element element = locate(locator); return session.getCursorPosition(element); } public Number getElementHeight(String locator) { return session.boundingRectangle(locate(locator)).height; } public Number getElementIndex(String locator) { Element element = locate(locator); NodeList childNodes = element.getParentNode().getChildNodes(); int index = 0; for (int i = 0; i < childNodes.getLength(); i++) { if (childNodes.item(i).getNodeType() == Element.ELEMENT_NODE) { index++; } if (element == childNodes.item(i)) { return index - 1; } } throw new IllegalStateException("Not a child of its parent: " + element); } public Number getElementPositionLeft(String locator) { return session.boundingRectangle(locate(locator)).x; } public Number getElementPositionTop(String locator) { return session.boundingRectangle(locate(locator)).y; } public Number getElementWidth(String locator) { return session.boundingRectangle(locate(locator)).width; } public String getEval(String script) { return getExpression(script); } public String getExpression(String expression) { try { return session.evaluate(expression); } finally { waitForIdle(); } } public String getHtmlSource() { try { StringWriter htmlAsString = new StringWriter(); OutputFormat format = new OutputFormat(); format.setOmitXMLDeclaration(true); new XMLSerializer(htmlAsString, format).serialize(session.dom()); return htmlAsString.toString(); } catch (IOException e) { throw new RuntimeException(e); } } public String getLocation() { return session.evaluate(session.getDocumentExpression() + ".location"); } public Number getMouseSpeed() { throw new UnsupportedOperationException(); } public String getPrompt() { if (!promptHandler.isDialogPresent()) { throw new IllegalStateException("No prompt present"); } return promptHandler.getMessage(); } public String[] getSelectOptions(String selectLocator) { Element select = locate(selectLocator); List<String> selectOptions = new ArrayList<String>(); NodeList options = select.getElementsByTagName("option"); for (int i = 0; i < options.getLength(); i++) { Element option = (Element) options.item(i); selectOptions.add(option.getTextContent()); } return selectOptions.toArray(new String[0]); } public String getSelectedId(String selectLocator) { return getSelectedIds(selectLocator)[0]; } public String[] getSelectedIds(String selectLocator) { Element select = locate(selectLocator); List<String> selectOptions = new ArrayList<String>(); NodeList options = select.getElementsByTagName("option"); for (int i = 0; i < options.getLength(); i++) { Element option = (Element) options.item(i); if (Boolean.parseBoolean(option.getAttribute("selected"))) { selectOptions.add(option.getAttribute("id")); } } return selectOptions.toArray(new String[0]); } public String getSelectedIndex(String selectLocator) { return getSelectedIndexes(selectLocator)[0]; } public String[] getSelectedIndexes(String selectLocator) { Element select = locate(selectLocator); List<String> selectOptions = new ArrayList<String>(); NodeList options = select.getElementsByTagName("option"); for (int i = 0; i < options.getLength(); i++) { Element option = (Element) options.item(i); if (Boolean.parseBoolean(option.getAttribute("selected"))) { selectOptions.add(i + ""); } } return selectOptions.toArray(new String[0]); } public String getSelectedLabel(String selectLocator) { return getSelectedLabels(selectLocator)[0]; } public String[] getSelectedLabels(String selectLocator) { Element select = locate(selectLocator); List<String> selectOptions = new ArrayList<String>(); NodeList options = select.getElementsByTagName("option"); for (int i = 0; i < options.getLength(); i++) { Element option = (Element) options.item(i); if (Boolean.parseBoolean(option.getAttribute("selected"))) { selectOptions.add(option.getTextContent()); } } return selectOptions.toArray(new String[0]); } public String getSelectedValue(String selectLocator) { return getSelectedValues(selectLocator)[0]; } public String[] getSelectedValues(String selectLocator) { Element select = locate(selectLocator); List<String> selectOptions = new ArrayList<String>(); NodeList options = select.getElementsByTagName("option"); for (int i = 0; i < options.getLength(); i++) { Element option = (Element) options.item(i); if (Boolean.parseBoolean(option.getAttribute("selected"))) { selectOptions.add(option.getAttribute("value")); } } return selectOptions.toArray(new String[0]); } public String getSpeed() { return speed + ""; } public String getTable(String tableCellAddress) { int columnIndex = tableCellAddress.lastIndexOf("."); int column = Integer.parseInt(tableCellAddress.substring(columnIndex + 1)); tableCellAddress = tableCellAddress.substring(0, columnIndex); int rowIndex = tableCellAddress.lastIndexOf("."); int row = Integer.parseInt(tableCellAddress.substring(rowIndex + 1)); tableCellAddress = tableCellAddress.substring(0, rowIndex); Element table = locate(tableCellAddress); Element rowElement = (Element) table.getElementsByTagName("tr").item(row); NodeList cells = rowElement.getElementsByTagName("td"); if (cells.getLength() == 0) { cells = rowElement.getElementsByTagName("th"); } return session.getText((Element) cells.item(column)); } public String getText(String locator) { return session.getText(locate(locator)); } public String getTitle() { return session.evaluate(session.getDocumentExpression() + ".title").trim(); } public String getValue(String locator) { return locate(locator).getAttribute("value"); } public boolean getWhetherThisFrameMatchFrameExpression(String currentFrameString, String target) { throw new UnsupportedOperationException(); } public boolean getWhetherThisWindowMatchWindowExpression(String currentWindowString, String target) { throw new UnsupportedOperationException(); } public Number getXpathCount(String xpath) { return session.locateAll(xpath).size(); } public void goBack() { session.getBrowser().back(); waitForIdle(); } public void highlight(String locator) { throw new UnsupportedOperationException(); } public void ignoreAttributesWithoutValue(String ignore) { } public boolean isAlertPresent() { return alertHandler.isDialogPresent(); } public boolean isChecked(String locator) { return Boolean.parseBoolean(locate(locator).getAttribute("checked")); } public boolean isConfirmationPresent() { return confirmationHandler.isDialogPresent(); } public boolean isCookiePresent(String name) { return getCookieByName(name) != null; } public boolean isEditable(String locator) { Element element = locate(locator); String tagName = element.getTagName().toLowerCase(); boolean editable = !(Boolean.parseBoolean(element.getAttribute("disabled")) || Boolean.parseBoolean(element .getAttribute("readonly"))); editable = editable && asList("input", "select", "textarea").contains(tagName); return editable; } public boolean isElementPresent(String locator) { try { locate(locator); return true; } catch (ElementNotFoundException e) { return false; } } public boolean isOrdered(String locator1, String locator2) { Element firstElement = locate(locator1); Element secondElement = locate(locator2); if (!firstElement.isEqualNode(secondElement) && firstElement.getParentNode().isEqualNode(secondElement.getParentNode())) { return indexOfNode(firstElement) < indexOfNode(secondElement); } return false; } private int indexOfNode(Element element) { int index = 0; NodeList siblings = element.getParentNode().getChildNodes(); for (; index < siblings.getLength(); index++) { if (siblings.item(index) == element) { break; } } return index; } public boolean isPromptPresent() { return promptHandler.isDialogPresent(); } public boolean isSomethingSelected(String selectLocator) { return getSelectedIndexes(selectLocator).length > 0; } public boolean isTextPresent(String pattern) { String text = getBodyText(); for (StringMatcher matcher : stringMatchers) { if (matcher.canMatch(pattern)) { return matcher.matches(pattern, text); } } return false; } public boolean isVisible(String locator) { return session.isVisible(locate(locator)); } public void keyDown(String locator, String keySequence) { throw new UnsupportedOperationException(); } public void keyDownNative(String keycode) { throw new UnsupportedOperationException(); } public void keyPress(String locator, String keySequence) { focus(locator); if (keySequence.startsWith("\\")) { keySequence = keySequence.substring("\\".length()); int keyCode = (char) Integer.parseInt(keySequence); switch (keyCode) { case KeyEvent.VK_DOWN: keyCode = SWT.ARROW_DOWN; break; case KeyEvent.VK_UP: keyCode = SWT.ARROW_UP; break; case KeyEvent.VK_LEFT: keyCode = SWT.ARROW_LEFT; break; case KeyEvent.VK_RIGHT: keyCode = SWT.ARROW_RIGHT; break; case KeyEvent.VK_PAGE_UP: keyCode = SWT.PAGE_UP; break; case KeyEvent.VK_PAGE_DOWN: keyCode = SWT.PAGE_DOWN; break; case KeyEvent.VK_HOME: keyCode = SWT.HOME; break; case KeyEvent.VK_END: keyCode = SWT.END; break; } user.key(keyCode); } else { user.key(keySequence.charAt(0)); } waitForIdle(); } public void keyPressNative(String keycode) { throw new UnsupportedOperationException(); } public void keyUp(String locator, String keySequence) { throw new UnsupportedOperationException(); } public void keyUpNative(String keycode) { throw new UnsupportedOperationException(); } public void metaKeyDown() { throw new UnsupportedOperationException(); } public void metaKeyUp() { throw new UnsupportedOperationException(); } public void mouseDown(String locator) { throw new UnsupportedOperationException(); } public void mouseDownAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void mouseMove(String locator) { throw new UnsupportedOperationException(); } public void mouseMoveAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void mouseOut(String locator) { throw new UnsupportedOperationException(); } public void mouseOver(String locator) { throw new UnsupportedOperationException(); } public void mouseUp(String locator) { throw new UnsupportedOperationException(); } public void mouseUpAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void open(String url) { try { checkModalDialogs(); if (url.startsWith("/")) { URL realUrl = new URL(browserUrl); url = new URL(realUrl.getProtocol(), realUrl.getHost(), realUrl.getPort(), url).toExternalForm(); } boolean isSameURL = url.equals(getLocation()) && !(session.getBrowserFamily() == BrowserFamily.SAFARI); if (isSameURL) { addLocationURLExclusionPattern(url); } session.execute(session.getDocumentExpression() + ".location = '" + url + "'"); waitForIdle(); if (isSameURL) { removeLocationURLExclusionPattern(url); } if (title != null && title.contains("404")) { throw new IllegalArgumentException("Page not found: " + url); } } catch (MalformedURLException e) { throw new RuntimeException(e); } } private void checkModalDialogs() { if (isAlertPresent() || isConfirmationPresent() || isPromptPresent()) { throw new IllegalStateException("Modal dialog present"); } } public void openWindow(String url, String windowID) { throw new UnsupportedOperationException(); } public void refresh() { session.getBrowser().setUrl(getLocation()); waitForIdle(); } public void removeAllSelections(String locator) { doSelection(locator, "", false, false); } public void removeSelection(String locator, String optionLocator) { doSelection(locator, optionLocator, true, false); } public void runScript(String script) { throw new UnsupportedOperationException(); } public void select(String selectLocator, String optionLocator) { doSelection(selectLocator, optionLocator, false, true); } private void doSelection(String selectLocator, String optionLocator, boolean multiselect, boolean shouldSelect) { Element select = locate(selectLocator); String indexPrefix = "index="; String labelPrefix = "label="; String valuePrefix = "value="; String idPrefix = "id="; if (!Boolean.parseBoolean(select.getAttribute("multiple")) && multiselect) { throw new IllegalArgumentException("Not a multi select: " + selectLocator); } fireEvent(select, "focus"); int currentIndex = 0; boolean wasSelected = false; NodeList childNodes = select.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { if (childNodes.item(i).getNodeType() != Element.ELEMENT_NODE) { continue; } Element option = (Element) childNodes.item(i); if (option.getNodeType() == Element.ELEMENT_NODE) { currentIndex++; } if (!multiselect) { setSelected(option, false); } if (optionLocator.startsWith(indexPrefix)) { int index = Integer.parseInt(optionLocator.substring(indexPrefix.length())); if (currentIndex - 1 == index) { wasSelected = true; setSelected(option, shouldSelect); break; } } else if (optionLocator.startsWith(valuePrefix)) { if (optionLocator.substring(valuePrefix.length()).equals(option.getAttribute("value"))) { wasSelected = true; setSelected(option, shouldSelect); break; } } else if (optionLocator.startsWith(idPrefix)) { if (optionLocator.substring(idPrefix.length()).equals(option.getAttribute("id"))) { wasSelected = true; setSelected(option, shouldSelect); break; } } else if (optionLocator.startsWith(labelPrefix)) { if (option.getTextContent().matches(optionLocator.substring(labelPrefix.length()))) { wasSelected = true; setSelected(option, shouldSelect); break; } } else { if (option.getTextContent().matches(optionLocator)) { wasSelected = true; setSelected(option, shouldSelect); break; } } } if (wasSelected) { fireEvent(select, "change"); } else { throw new IllegalArgumentException("No such option: " + optionLocator); } } private void setSelected(Element element, boolean value) { setProperty(element, "selected", "" + value); } private void setProperty(Element element, String property, String value) { session.execute(session.domExpression(element) + "." + property + " = " + value); } public void selectFrame(String locator) { if (locator.startsWith("index=")) { int index = Integer.parseInt(locator.substring(locator.indexOf("=") + 1)); session.setWindowExpression(session.getWindowExpression() + ".frames[" + index + "]"); } else if (locator.startsWith("relative=")) { String relation = locator.substring(locator.indexOf("=") + 1); if ("top".equals(relation)) { session.setWindowExpression("window"); return; } else if ("parent".equals(relation) || "up".equals(relation)) { session.setWindowExpression(session.getWindowExpression() + ".parent"); } } else if (new DomLocatorStrategy().canLocate(locator)) { if (locator.startsWith("dom=")) { locator = locator.substring("dom=".length()); } if (!"undefined".equals(session.evaluate("typeof " + locator + ".tagName"))) { session.setWindowExpression(locator + ".contentWindow"); } else { session.setWindowExpression(locator); } } else { Element frame = locate(locator); String domExpression = session.domExpression(frame); session.setWindowExpression(domExpression + ".contentWindow"); } } public void selectWindow(String windowID) { throw new UnsupportedOperationException(); } public void setBrowserLogLevel(String logLevel) { throw new UnsupportedOperationException(); } public void setContext(String context) { } public void setCursorPosition(String locator, String position) { Element element = locate(locator); // fireEvent(element, "focus"); session.setCursorPosition(element, Integer.parseInt(position)); } public void setMouseSpeed(String pixels) { throw new UnsupportedOperationException(); } public void setSpeed(String value) { this.speed = Integer.parseInt(value); if (speed < 0) { speed = 0; } } public void setTimeout(String timeout) { session.setEventLoopTimeout(Integer.parseInt(timeout)); } public void shiftKeyDown() { user.shiftDown(); } public void shiftKeyUp() { user.shiftUp(); } public void shutDownSeleniumServer() { throw new UnsupportedOperationException(); } public void start() { session.openBrowser(); init(); } public void stop() { session.closeBrowser(); } public void submit(String formLocator) { Element form = locate(formLocator); NodeList inputs = form.getElementsByTagName("input"); for (int i = 0; i < inputs.getLength(); i++) { Element item = (Element) inputs.item(i); if ("submit".equals(item.getAttribute("type"))) { click(item); break; } } } public void type(String locator, String value) { Element element = locate(locator); session.execute(session.domExpression(element) + ".value = ''"); typeKeys(element, value); } public void typeKeys(String locator, String value) { typeKeys(locate(locator), value); } private void typeKeys(Element element, String value) { if (BrowserFamily.IE == session.getBrowserFamily()) { // Don't like this, but it makes it more consistent in IE. session.execute(session.domExpression(element) + ".focus()"); } else { click(element); } user.type(value); waitForIdle(); } public void uncheck(String locator) { if (isChecked(locator)) { click(locator); } } public void waitForCondition(String script, String timeout) { throw new UnsupportedOperationException(); } public void waitForFrameToLoad(String frameAddress, String timeout) { } public void waitForPageToLoad(String timeout) { } public void waitForPopUp(String windowID, String timeout) { throw new UnsupportedOperationException(); } public void windowFocus() { session.getBrowser().forceFocus(); } public void windowMaximize() { session.getBrowser().getShell().setMaximized(true); } public void addAjaxURLExclusionPattern(String pattern) { ajaxWaitStrategy.addURLExclusionPattern(pattern); } public void addLocationURLExclusionPattern(String pattern) { documentReadyWaitStrategy.addURLExclusionPattern(pattern); } private void removeLocationURLExclusionPattern(String pattern) { documentReadyWaitStrategy.removeURLExclusionPattern(pattern); } public void setExcludedWaitURLs(String urls) { for (String pattern : urls.split(",")) { addLocationURLExclusionPattern(pattern); } } private Element locate(String locator) { Element locate = session.locate(locator); session.execute(session.domExpression(locate) + ".scrollIntoView(false)"); return locate; } private void click(Element element) { Point center = session.center(element); user.click(center.x, center.y); waitForIdle(); } // private void showPoint(Point point) { // session.execute( // "function() { var div = document.createElement('div'); div.setAttribute('style', 'position: absolute; border: 1px solid red; top: " // + (point.y - 2) + "; left: " + (point.x - 2) + // "; width: 5px; height: 5px;'); document.body.appendChild(div); setTimeout(function() {div.parentNode.removeChild(div);}, 2000);}()" // ); // } private void addStringMatchers() { stringMatchers.add(new RegexpMatcher()); stringMatchers.add(new ExactMatcher()); stringMatchers.add(new GlobMatcher()); } private void addWaitStrategies(final BrowserSession session) { ajaxWaitStrategy = new AjaxWaitStrategy(); session.addWaitStrategy(ajaxWaitStrategy); documentReadyWaitStrategy = new DocumentReadyWaitStrategy(); session.addWaitStrategy(documentReadyWaitStrategy); session.addWaitStrategy(new SetTimeoutWaitStrategy()); } private void addLocatorStrategies(final BrowserSession session) { session.addLocatorStrategy(new DomLocatorStrategy()); session.addLocatorStrategy(new CssSelectorLocatorStrategy()); session.addLocatorStrategy(new XPathLocatorStrategy()); session.addLocatorStrategy(new LinkLocatorStrategy()); session.addLocatorStrategy(new IdLocatorStrategy()); session.addLocatorStrategy(new NameLocatorStrategy()); session.addLocatorStrategy(new AltLocatorStrategy()); session.addLocatorStrategy(new ClassLocatorStrategy()); session.addLocatorStrategy(new IdentifierLocatorStrategy()); } private void waitForIdle() { session.waitForIdle(); } public void closeAllDialogs() { for (DialogHandler handler : getDialogHandlers()) { while (handler.isDialogPresent()) { handler.getMessage(); } } } private DialogHandler[] getDialogHandlers() { return new DialogHandler[] { alertHandler, confirmationHandler, promptHandler }; } public void addScript(String scriptContent, String scriptTagId) { throw new UnsupportedOperationException(); } public void captureEntirePageScreenshot(String filename, String kwargs) { throw new UnsupportedOperationException(); } public String captureEntirePageScreenshotToString(String kwargs) { throw new UnsupportedOperationException(); } public String captureScreenshotToString() { throw new UnsupportedOperationException(); } public void mouseDownRight(String locator) { throw new UnsupportedOperationException(); } public void mouseDownRightAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void mouseUpRight(String locator) { throw new UnsupportedOperationException(); } public void mouseUpRightAt(String locator, String coordString) { throw new UnsupportedOperationException(); } public void removeScript(String scriptTagId) { throw new UnsupportedOperationException(); } public String retrieveLastRemoteControlLogs() { throw new UnsupportedOperationException(); } public void rollup(String rollupName, String kwargs) { throw new UnsupportedOperationException(); } public void setExtensionJs(String extensionJs) { throw new UnsupportedOperationException(); } public void showContextualBanner() { throw new UnsupportedOperationException(); } public void showContextualBanner(String className, String methodName) { throw new UnsupportedOperationException(); } public void start(String optionsString) { throw new UnsupportedOperationException(); } public void start(Object optionsObject) { throw new UnsupportedOperationException(); } public void useXpathLibrary(String libraryName) { throw new UnsupportedOperationException(); } }