/** * Accepts a command reply, and retrieves the next command to run. * * @param commandResult - the reply from the previous command, or null * @param incomingFrameAddress - frame from which the reply came * @param uniqueId * @param justLoaded * @param jsWindowNameVars * @return - the next command to run */ public RemoteCommand handleCommandResult( String commandResult, FrameAddress incomingFrameAddress, String uniqueId, boolean justLoaded, List<?> jsWindowNameVars) { CommandQueue queue = getCommandQueue(uniqueId); queue.setFrameAddress(incomingFrameAddress); if (jsWindowNameVars != null) { for (Object jsWindowNameVar : jsWindowNameVars) { queue.addJsWindowNameVar((String) jsWindowNameVar); } } if (justLoaded) { markWhetherJustLoaded(uniqueId, true); commandResult = null; } if (WindowClosedException.WINDOW_CLOSED_ERROR.equals(commandResult)) { queue.declareClosed(); return new DefaultRemoteCommand("testComplete", "", ""); } return queue.handleCommandResult(commandResult); }
private void setCurrentFrameAddress(String uniqueId) { assert uniqueId != null; FrameAddress frameAddress = uniqueIdToCommandQueue.get(uniqueId).getFrameAddress(); this.currentUniqueId = uniqueId; this.currentFrameAddress = frameAddress; this.currentSeleniumWindowName = frameAddress.getWindowName(); this.currentLocalFrameAddress = frameAddress.getLocalFrameAddress(); markWhetherJustLoaded(uniqueId, false); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Current uniqueId set to " + uniqueId + ", frameAddress = " + frameAddress); } }
private String waitForLoad( String waitingForThisWindowName, String waitingForThisLocalFrame, int timeoutInSeconds) throws RemoteCommandException { for (String matchingFrameAddress = null; timeoutInSeconds >= 0; timeoutInSeconds--) { dataLock.lock(); try { LOGGER.debug( "waiting for window '" + waitingForThisWindowName + "' local frame '" + waitingForThisLocalFrame + "' for " + timeoutInSeconds + " more secs"); matchingFrameAddress = findMatchingFrameAddress( frameAddressToJustLoaded.keySet(), waitingForThisWindowName, waitingForThisLocalFrame); if (null != matchingFrameAddress) { LOGGER.debug( "wait is over: window '" + waitingForThisWindowName + "' was seen at last (" + matchingFrameAddress + ")"); /* * Remove it from the list of matching frame addresses * since it just loaded. Mark whether just loaded * to aid debugging. */ markWhetherJustLoaded(matchingFrameAddress, false); return matchingFrameAddress; } waitUntilSignalOrNumSecondsPassed(resultArrivedOnAnyQueue, 1); } finally { dataLock.unlock(); } } String result = "timed out waiting for window '" + waitingForThisWindowName + "' to appear"; throw new RemoteCommandException(result, result); }
/** * Does uniqueId point at a window that matches 'windowName'/'localFrame'? * * @param uniqueId * @param windowName * @param localFrame * @return True if the frame addressed by uniqueId is addressable by window name 'windowName' and * local frame address 'localFrame'. */ private boolean matchesFrameAddress(String uniqueId, String windowName, String localFrame) { // it's an odd selenium convention: "null" maps to the initial, main window: if (windowName == null || windowName.equals("null")) { windowName = DEFAULT_SELENIUM_WINDOW_NAME; } if (localFrame == null) { localFrame = "top"; } CommandQueue queue = uniqueIdToCommandQueue.get(uniqueId); if (queue.isClosed()) { return false; } boolean windowJustLoaded = justLoaded(uniqueId); FrameAddress frameAddress = queue.getFrameAddress(); if (!frameAddress.getLocalFrameAddress().equals(localFrame)) { return false; } // DGF Windows that have just loaded may not know their true identity if (windowJustLoaded) { String title; try { title = getRemoteWindowTitle(queue); } catch (WindowClosedException e) { return false; } markWhetherJustLoaded(uniqueId, true); if (title.equals(windowName)) { return true; } } String actualWindowName = frameAddress.getWindowName(); if (windowName.equals(actualWindowName)) { return true; } if (windowName.equals("_blank") && actualWindowName.startsWith("selenium_blank")) { // DGF the API automatically changed target="_blank" to target="selenium_blank12345" return true; } return uniqueIdToCommandQueue.get(uniqueId).isWindowPointedToByJsVariable(windowName); }
/** * Schedules the specified command to be retrieved by the next call to handle command result, and * returns the result of that command. * * @param command - the remote command verb * @param arg - the first remote argument (meaning depends on the verb) * @param value - the second remote argument * @return - the command result, defined by the remote JavaScript. "getX" style commands may * return data from the browser; other "doX" style commands may just return "OK" or an error * message. * @throws RemoteCommandException if a waitForLoad failed. */ public String doCommand(String command, String arg, String value) throws RemoteCommandException { if (proxyInjectionMode) { if (command.equals("selectFrame")) { if ("".equals(arg)) { arg = "top"; } boolean newFrameFound = false; // DGF iterate in lexical order for testability Set<String> idSet = uniqueIdToCommandQueue.keySet(); String[] ids = idSet.toArray(new String[0]); Arrays.sort(ids); for (String uniqueId : ids) { CommandQueue frameQ = uniqueIdToCommandQueue.get(uniqueId); if (frameQ.isClosed()) { continue; } FrameAddress frameAddress = frameQ.getFrameAddress(); if (frameAddress.getWindowName().equals(currentSeleniumWindowName)) { if (queueMatchesFrameAddress(frameQ, currentLocalFrameAddress, arg)) { setCurrentFrameAddress(uniqueId); newFrameFound = true; break; } } } if (!newFrameFound) { return "ERROR: starting from frame " + currentFrameAddress + ", could not find frame " + arg; } return "OK"; } if (command.equals("selectWindow")) { return selectWindow(arg); } if (command.equals("waitForPopUp")) { String waitingForThisWindowName = arg; long timeoutInMilliseconds = Long.parseLong(value); String uniqueId; try { // Wait for the popup window to load, if it throws // an exception then we should simply return the // command result uniqueId = waitForLoad(waitingForThisWindowName, "top", (int) (timeoutInMilliseconds / 1000l)); // if (!result.equals("OK")) { // return result; // } } catch (RemoteCommandException ex) { return ex.getResult(); } // Return the result of selecting the frame address, not the window name setCurrentFrameAddress(uniqueId); return "OK"; } if (command.equals("waitForPageToLoad")) { return waitForLoad(arg); } if (command.equals("waitForFrameToLoad")) { String waitingForThisFrameName = arg; long timeoutInMilliseconds = Long.parseLong(value); String currentWindowName = getCommandQueue().getFrameAddress().getWindowName(); String result; try { result = waitForLoad( currentWindowName, waitingForThisFrameName, (int) (timeoutInMilliseconds / 1000l)); } catch (RemoteCommandException e) { return e.getMessage(); } setCurrentFrameAddress(result); return "OK"; } if (command.equals("setTimeout")) { try { pageLoadTimeoutInMilliseconds = Integer.parseInt(arg); } catch (NumberFormatException e) { return "ERROR: setTimeout arg is not a number: " + arg; } return "OK"; } if (command.equals("getAllWindowNames")) { return getAttributeFromAllWindows("name"); } if (command.equals("getAllWindowTitles")) { return getAttributeFromAllWindows("document.title"); } if (command.equals("getAllWindowIds")) { return getAttributeFromAllWindows("id"); } if (command.equals("getAttributeFromAllWindows")) { return getAttributeFromAllWindows(arg); } // handle closed queue (the earlier commands don't care about closed queues) CommandQueue queue = getCommandQueue(); if (queue.isClosed()) { try { String uniqueId = waitForLoad(currentSeleniumWindowName, currentLocalFrameAddress, 1); setCurrentFrameAddress(uniqueId); } catch (RemoteCommandException e) { return WindowClosedException.WINDOW_CLOSED_ERROR; } } if (command.equals("open")) { markWhetherJustLoaded(currentUniqueId, false); String t = getCommandQueue().doCommand(command, arg, value); if (!"OK".equals(t)) { return t; } return waitForLoad(pageLoadTimeoutInMilliseconds); } // strip off AndWait - in PI mode we handle this in the server rather than in core... if (command.endsWith("AndWait")) { markWhetherJustLoaded(currentUniqueId, false); command = command.substring(0, command.length() - "AndWait".length()); String t = getCommandQueue().doCommand(command, arg, value); if (!t.startsWith("OK")) { return t; } return waitForLoad(pageLoadTimeoutInMilliseconds); } } // if (proxyInjectionMode) markWhetherJustLoaded(currentUniqueId, false); return getCommandQueue().doCommand(command, arg, value); }