Skip to content

Commit

Permalink
Implement {get,set}CursorPosition for the RC emulation.
Browse files Browse the repository at this point in the history
Again, enough to get the core test to pass. No idea if it works.
  • Loading branch information
shs96c committed Jul 27, 2016
1 parent 5dec77c commit dd44b43
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 13 deletions.
3 changes: 2 additions & 1 deletion java/client/src/com/thoughtworks/selenium/webdriven/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ java_library(name = 'webdriven',
':isSomethingSelected',
':isTextPresent',
':isVisible',
':setCursorPosition',
':type',
# TODO(simons): remove sizzle. There are no longer any browsers that need it.
':sizzle',
Expand Down Expand Up @@ -67,7 +68,7 @@ java_library(name = 'emulation-api',

for name in ['findElement', 'findOption', 'fireEvent', 'fireEventAt', 'getAttribute', 'getText',
'linkLocator', 'isElementPresent', 'isSomethingSelected', 'isTextPresent',
'isVisible', 'type',]:
'isVisible', 'setCursorPosition', 'type',]:
export_file(name = name,
out = '%s.js' % name,
src = '//javascript/selenium-atoms:%s' % name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void setDefaultTimeout(long defaultTimeout) {
this.defaultTimeout = defaultTimeout;
}

protected long getTimeout(String timeout) {
protected long toLong(String timeout) {
// Of course, a non-breaking space doesn't count as whitespace.
timeout = timeout.replace('\u00A0',' ').trim();
return "".equals(timeout) ? defaultTimeout : Long.valueOf(timeout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ private void setUpMethodMap() {
seleneseMethods.put("getConfirmation", new GetConfirmation(alertOverride));
seleneseMethods.put("getCookie", new GetCookie());
seleneseMethods.put("getCookieByName", new GetCookieByName());
seleneseMethods.put("getCursorPosition", new GetCursorPosition(elementFinder));
seleneseMethods.put("getElementHeight", new GetElementHeight(elementFinder));
seleneseMethods.put("getElementIndex", new GetElementIndex(elementFinder,
javascriptLibrary));
Expand Down Expand Up @@ -319,6 +320,9 @@ private void setUpMethodMap() {
seleneseMethods.put("selectWindow", new SelectWindow(windows));
seleneseMethods.put("setBrowserLogLevel", new NoOp(null));
seleneseMethods.put("setContext", new NoOp(null));
seleneseMethods.put(
"setCursorPosition",
new SetCursorPosition(javascriptLibrary, elementFinder));
seleneseMethods.put("setSpeed", new NoOp(null));
seleneseMethods.put("setTimeout", new SetTimeout(timer));
seleneseMethods.put("shiftKeyDown", new ShiftKeyDown(keyState));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public void replaceAlertMethod(WebDriver driver) {
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true)); " +
" return res; " +
" }; " +
" window.localStorage.setItem('__webdriverPrompts', JSON.stringify([])); " +
" if (!('__webdriverNextPrompt' in window.localStorage)) { " +
" window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(true)); " +
" } " +
" window.prompt = function(msg, def) { " +
" var prompts = JSON.parse(window.localStorage.getItem('__webdriverPrompts')); " +
" prompts.push(msg || def); " +
" window.localStorage.setItem('__webdriverPrompts', JSON.stringify(prompts)); " +
" var res = JSON.parse(window.localStorage.getItem('__webdriverNextPrompts')); " +
" window.localStorage.setItem('__webdriverNextPrompts', JSON.stringify(true)); " +
" return res; " +
" }; " +
"} else { " +
" if (window.__webdriverAlerts) { return; } " +
" window.__webdriverAlerts = []; " +
Expand All @@ -73,6 +85,14 @@ public void replaceAlertMethod(WebDriver driver) {
" window.__webdriverNextConfirm = true; " +
" return res; " +
" }; " +
" window.__webdriverPrompts = []; " +
" window.__webdriverNextPrompts = true; " +
" window.prompt = function(msg, def) { " +
" window.__webdriverPrompt.push(msg || def); " +
" var res = window.__webdriverNextPrompt; " +
" window.__webdriverNextPrompt = true; " +
" return res; " +
" }; " +
"}"
);
}
Expand Down Expand Up @@ -173,4 +193,21 @@ public boolean isConfirmationPresent(WebDriver driver) {
"}"
));
}

public boolean isPromptPresent(WebDriver driver) {
checkOverridesEnabled();
return Boolean.TRUE.equals(((JavascriptExecutor) driver).executeScript(
"var canUseLocalStorage = false; " +
"try { canUseLocalStorage = !!window.localStorage; } catch(ex) { /* probe failed */ } " +
"var canUseJSON = false; " +
"try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ } " +
"if (canUseLocalStorage && canUseJSON) { " +
" if (!('__webdriverPrompts' in window.localStorage)) { return false } " +
" var prompts = JSON.parse(window.localStorage.getItem('__webdriverPrompts')); " +
" return prompts && prompts.length > 0; " +
"} else { " +
" return window.__webdriverPrompts && window.__webdriverPrompts.length > 0; " +
"}"
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
import org.openqa.selenium.WebDriver;

public class AnswerOnNextPrompt extends SeleneseCommand<Void> {
private final boolean result;

public AnswerOnNextPrompt(boolean result) {
this.result = result;
}

@Override
protected Void handleSeleneseCommand(WebDriver driver, String locator, String value) {
Expand All @@ -37,11 +32,11 @@ protected Void handleSeleneseCommand(WebDriver driver, String locator, String va
"var canUseJSON = false; " +
"try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ } " +
"if (canUseLocalStorage && canUseJSON) { " +
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(arguments[0])); " +
" window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(arguments[0])); " +
"} else { " +
" window.__webdriverNextConfirm = arguments[0];" +
"}"
, result);
" window.__webdriverNextPrompt = arguments[0];" +
"}",
locator);
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you 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.

package com.thoughtworks.selenium.webdriven.commands;

import com.google.common.base.Joiner;

import com.thoughtworks.selenium.webdriven.ElementFinder;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class GetCursorPosition extends com.thoughtworks.selenium.webdriven.SeleneseCommand<Number> {

private final ElementFinder finder;

public GetCursorPosition(ElementFinder finder) {
this.finder = finder;
}

@Override
protected Number handleSeleneseCommand(WebDriver driver, String locator, String value) {
// All supported browsers apparently support "document.selection". Let's use that and the
// relevant snippet of code from the original selenium core to implement this. What could
// possibly go wrong?

WebElement element = finder.findElement(driver, locator);

return (Number) ((JavascriptExecutor) driver).executeScript(
Joiner.on("\n").join(
"try {",
" var selectRange = document.selection.createRange().duplicate();",
" var elementRange = arguments[0].createTextRange();",
" selectRange.move('character', 0)",
" elementRange.move('character', 0);",
" var inRange1 = selectRange.inRange(elementRange);",
" var inRange2 = elementRange.inRange(selectRange);",
" elementRange.setEndPoint('EndToEnd', selectRange);",
"} catch (e) {",
" throw Error('There is no cursor on this page!');",
"}",
"return String(elementRange.text).replace(/\r/g,' ').length;"),
element);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you 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.

package com.thoughtworks.selenium.webdriven.commands;

import com.thoughtworks.selenium.webdriven.ElementFinder;
import com.thoughtworks.selenium.webdriven.JavascriptLibrary;
import com.thoughtworks.selenium.webdriven.SeleneseCommand;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;

public class SetCursorPosition extends SeleneseCommand<Void> {

private final JavascriptLibrary library;
private final ElementFinder finder;

public SetCursorPosition(JavascriptLibrary library, ElementFinder finder) {
this.library = library;
this.finder = finder;
}


@Override
protected Void handleSeleneseCommand(WebDriver driver, String locator, String value) {
WebElement element = finder.findElement(driver, locator);
long position = toLong(value);

String setPosition = library.getSeleniumScript("getText.js");

((JavascriptExecutor) driver).executeScript(
"(" + setPosition + ")(arguments[0], arguments[1]);",
element,
position);

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public WaitForPopup(Windows windows) {
@Override
protected Void handleSeleneseCommand(final WebDriver driver, final String windowID,
final String timeout) {
final long millis = getTimeout(timeout);
final long millis = toLong(timeout);
final String current = driver.getWindowHandle();

new Wait() {
Expand Down
7 changes: 7 additions & 0 deletions javascript/selenium-atoms/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ js_fragment(name = 'isVisible',
visibility = [ '//java/client/src/com/thoughtworks/selenium/webdriven:isVisible' ],
)

js_fragment(name = 'setCursorPosition',
module = 'core.text',
function = 'core.text.setCursorPosition',
deps = [':deps'],
visibility = [ '//java/client/src/com/thoughtworks/selenium/webdriven:setCursorPosition' ],
)

js_fragment(name = 'type',
module = 'core.events',
function = 'core.events.setValue',
Expand Down
27 changes: 27 additions & 0 deletions javascript/selenium-atoms/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ goog.provide('core.text');


goog.require('bot');
goog.require('bot.events');
goog.require('bot.userAgent');
goog.require('core.patternMatcher');
goog.require('goog.dom');
Expand Down Expand Up @@ -220,3 +221,29 @@ core.text.linkLocator = function(locator, opt_doc) {
}
return null;
};


/**
* Set a new caret position within an element.
*
* @param {!Element} element The element to use.
* @param {number} position The new caret position.
*/
core.text.setCursorPosition = function(element, position) {
if (position == -1) {
position = element.value.length;
}

if (element.setSelectionRange) {
element.focus();
element.setSelectionRange(/*start*/ position, /*end*/ position);
} else if (element.createTextRange) {
bot.events.fire(element, bot.events.EventType.FOCUS);
var range = element.createTextRange();
range.collapse(true);
range.moveEnd('character', position);
range.moveStart('character', position);
range.select();
}
};

1 change: 0 additions & 1 deletion javascript/selenium-core/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ zip_file(
':core',
],
visibility = [
'//java/server/src/org/openqa/selenium/server:selenium-core',
'//java/server/test/org/openqa/selenium:core-scripts',
],
)
Expand Down

0 comments on commit dd44b43

Please sign in to comment.