|
Лекция 2-3. Лекция Изучение расширенных взаимодействий WebDriver Понимание действий, построение и выполнение
Лекция 2. Изучение расширенных взаимодействий WebDriver
Понимание действий, построение и выполнение
Рассмотрим простой сценарий. Откройте файл selectable.html приложенный к этой книге. Вы увидите плитки с числами от 1 до 12. Если вы проверите эти элементы в Firebug, вы увидите тег упорядоченного списка () и 12 элементов списка (- ) в нем:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Выглядит как таблица:
-
1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
|
При клике на какое-либо число его фоновый цвет меняется на оранжевый. Попробуйте выбрать 1, 3 и 5 нумерованные плитки, удерживая клавишу Ctrl+ плитку 1 + плитку 3 + плитку 5. Это задействует несколько действий: удерживание Ctrlи щелчок по 1, 3 и 5 tiles. Как мы выполним эти несколько действий при помощи WebDriver? public class ActionBuildPerform {
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/selectable.html");
WebElement one = driver.findElement(By.name("one")); WebElement three = driver.findElement(By.name("three"));
WebElement five = driver.findElement(By.name("five"));
// Add all the actions into the Actions builder.
Actions builder = new Actions(driver); builder.keyDown(Keys.CONTROL)
.click(one)
.click(three)
.click(five)
.keyUp(Keys.CONTROL);
// Generate the composite action.
Action compositeAction = builder.build();
// Perform the composite action.
compositeAction.perform();
}
} В строке 9 мы встречаемся с новым классом Actions. Он используется для эмуляции всех составных действий пользователя. При помощи его тестировщик может комбинировать все необходимые gestures пользователя в одно composite действие. В строках 9-14 мы объявили все действия, которые необходимо выполнить, чтобы достигнуть функциональности щелчка по числам 1, 3 и 5. Когда все действия сгруппированы, мы строим их в составное действие в строке 16. Action – это интерфейс, который имеет только метод perform(), выполняющий составное действие. В строке 18 мы собственно выполняем действие с помощью этого метода.
Итак, чтобы заставить WebDriver выполнить несколько действий за один раз, необходимо следовать трехшаговому процессу использования пользовательского API класса Actions для группировки всех действий, затем построить составное действие и выполнить его. Этот процесс можно сократить до двух шагов, поскольку метод perform() внутренне вызывает метод build(): public class ActionBuildPerform {
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/selectable.html");
WebElement one = driver.findElement(By.name("one")); WebElement three = driver.findElement(By.name("three"));
WebElement five = driver.findElement(By.name("five"));
// Add all the actions into the Actions builder.
Actions builder = new Actions(driver); builder.keyDown(Keys.CONTROL)
.click(one)
.click(three)
.click(five)
.keyUp(Keys.CONTROL);
// Perform the action.
builder.perform();
}
} Мы прямо вызвали метод perform() экземпляра класса Actions, который внутренне вызывает метод build()для создания составного действия прежде его выполнения.
Действия делятся на две категории:
Основанные на мыши
Основанные на клавиатуре
Основанные на мыши взаимодействия
Существует 8 действий мыши, которые могут быть выполнены при помощи класса Actions. Действие moveByOffset
Метод moveByOffset()используется для перемещения курсора мыши с его текущего положения в другую точку веб-страницы. Разработчик может задать расстояния X и Y , на которые следует переместить мышь. При загрузке страницы обычно начальное положение мыши (0, 0), если точный фокус не задан этой страницей.
Синтаксис API метода moveByOffset():
public Actions moveByOffset(int xOffSet, int yOffSet)
xOffSet - смещение по оси x (>0 – направо, <0 – налево)
yOffSet – по оси y (>0 – вниз, <0 – вверх)
Если значения xOffSet и yOffSet заданы так, что курсор вышел за границы документа, генерируется исключение MoveTargetOutOfBoundsException.
Рассмотрим рабочий пример. Переместим курсор к числу 3 на той же самой веб-странице: public class MoveByOffSet{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Selectable.html");
WebElement three = driver.findElement(By.name("three")); System.out.println("X coordinate: "+three.getLocation().getX()+"
Y coordinate: "+three.getLocation().getY());
Actions builder = new Actions(driver);
builder.moveByOffset(three.getLocation().getX()+1, three. getLocation().getY()+1);
builder.perform();
}
}
Мы добавили +1 к координатам, поскольку, если вы наблюдали этот элемент в Firebug, в стиле задана граница в 1 px. Border – атрибут стилей CSS, который при применении к элементу добавит вокруг этого элемента границу заданного цвета с заданной толщиной. Хотя предыдущий код передвигает указатель мыши к tile 3, мы это не понимаем, поскольку не выполняем здесь никаких действий. Мы увидим это, когда применим этот метод
moveByOffset()в комбинации с методом click().
Метод moveByOffset() может не работать в Mac OSX и может вызвать ошибку JavaScript при выполнении независимо, как в предыдущем коде.
Действие для щелчка в текущей позиции
Метод click()используется для эмуляции щелчка левой кнопкой мыши по текущей позиции. Этот метод не понимает, где или по какому элементу кликает. Он просто слепо кликает там, где находится в этот момент. Таким образом, этот метод используется не самостоятельно, а в комбинации с каким-либо другим действием для создания составного действия.
Синтаксис API для метода click():
public Actions click()
Метод click()не имеет входных параметров.
Рассмотрим пример:
public class MoveByOffsetAndClick{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Selectable.html");
WebElement seven = driver.findElement(By.name("seven"));
System.out.println("X coordinate: "+seven.getLocation().getX()+" Y coordinate: "+seven.getLocation().getY());
Actions builder = new Actions(driver);
builder.moveByOffset(seven.getLocation().getX()+1, seven. getLocation().getY()+1).click();
builder.perform();
}
}
В строке 8 мы использовали комбинацию методов moveByOffset() и click() для перемещения курсора из точки (0, 0) в точку, где находится плитка 7. Поскольку начальное положение мыши (0, 0), смещение X, Y , переданное в метод moveByOffset()- это просто расположение плитки 7.
Теперь переместим курсор из tile 1 к tile 11, а оттуда к tile 5. Прежде чем посмотреть на код, изучим страницу selectable.html при помощи Firebug. Вот стиль каждой плитки: #selectable li { float: left; font-size: 4em; height: 80px;
text-align: center;
width: 100px;
}
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
background: url("images/ui-bg_glass_75_e6e6e6_1x400.png") repeat-x scroll 50% 50% #E6E6E6;
border: 1px solid #D3D3D3;
color: #555555;
font-weight: normal;
}
Итак, height = 80px, width = 100px, border = 1px. Используем эти три значения, чтобы вычислить смещение для перемещения от одной плитки к другому. Отметим, что толщина границы между двумя плитками равна 2 px (по одному пикселю от каждой плитки). В следующем коде с помощью методов moveByOffset и click()происходит перемещение от плитки 1 к плитке 11, а оттуда к плитке 5: public class MoveByOffsetAndClick{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Selectable.html");
WebElement one = driver.findElement(By.name("one")); WebElement eleven = driver.findElement(By.name("eleven")); WebElement five = driver.findElement(By.name("five"));
int border = 1;
int tileWidth = 100; int tileHeight = 80;
Actions builder = new Actions(driver);
//Click on One
builder.moveByOffset(one.getLocation().getX()+border, one. getLocation().getY()+border).click();
builder.build().perform();
// Click on Eleven
builder.moveByOffset(2*tileWidth+4*border, 2*tileHeight+4*border). click();
builder.build().perform();
//Click on Five
builder.moveByOffset(-2*tileWidth-4*border,-tileHeight-2*border). click();
builder.build().perform();
}
} Действие для щелчка по WebElement
Не обязательно каждый раз вычислять смещение для WebElementа, особенно когда он имеет собственные идентификаторы – имя или ID. Существует другая перегруженная версия метода click()для щелчка непосредственно на WebElement.
Синтаксис API для щелчка по веб-элементу:
public Actions click(WebElement onElement) Входной параметр – экземпляр класса WebElement, над которым необходимо выполнить действие click. Этот метод, как все остальные в классе Actions, вернет экземпляр Actions.
Изменим предыдущий код для использования метода click(WebElement) вместо метода moveByOffset(), чтобы переместиться к расположению веб-элемента и кликнуть на нем при помощи метода click(): public class ClickOnWebElement{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Selectable.html");
WebElement one = driver.findElement(By.name("one")); WebElement eleven = driver.findElement(By.name("eleven")); WebElement five = driver.findElement(By.name("five")); Actions builder = new Actions(driver);
//Click on One builder.click(one); builder.build().perform();
// Click on Eleven builder.click(eleven); builder.build().perform();
//Click on Five builder.click(five) builder.build().perform();
}
} Теперь вся сложная координатная геометрия исчезла из кода.
Если вы присмотритесь к предыдущему коду или к коду классов moveByOffset и click, все операции перемещения мыши и щелчка по плиткам one, eleven, и five построены отдельно и выполнены отдельно. Не так, как мы используем наш класс Actions.
Т.к. click() возвращает Actions то можно использовать последовательный вызов методов1. Поэтому мы можем построить все действия вместе и затем выполнить их: public class ClickOnWebElement{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Selectable.html");
WebElement one = driver.findElement(By.name("one")); WebElement eleven = driver.findElement(By.name("eleven")); WebElement five = driver.findElement(By.name("five")); Actions builder = new Actions(driver);
//Click on One, Eleven and Five builder.click(one).click(eleven).click(five); builder.build().perform();
}
} Действие для щелчка с удержанием по текущему расположению
Метод clickAndHold()- другой метод класса Actions , который эмулирует щелчок левой кнопкой мыши по элементу и удержание ее, не отпуская кнопку. Этот метод будет полезен при выполнении таких операций как перетаскивание. Класс clickAndHold() предоставляет различные варианты данного метода.
Откройте файл Sortable.html. Плитки переместились в другое положение. Переместим плитку 3 на место плитки 2. Для этого необходимо выполнить следующие шаги:
Переместить курсор в позицию плитки 3.
Щелкнуть и удержать плитку 3.
Переместить курсор к позиции плитки 2.
Вот как это можно сделать при помощи метода clickAndHold():
public class ClickAndHold{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Sortable.html"); Actions builder = new Actions(driver);
//Move tile3 to the position of tile2
builder.moveByOffset(200, 20)
.clickAndHold()
.moveByOffset(120, 0)
.perform();
}
}
Мы перемещаем курсор к позиции плитки 3. Затем щелкаем по плитке 3 и удерживаем кнопку мыши. Затем перемещаем курсор на 120px по горизонтали к позиции плитки 2. Последняя строка выполняет все перечисленные действия. Теперь выполните этот код в вашем eclipse. Если вы заметите, наша плитка 3 не переместитс в позицию плитки 2. Дело в том, что мы еще не отпустили левую кнопку мыши. Ниже мы рассмотрим метод release(). Действие для щелчка с удержанием по веб-элементу
В предыдущем разделе мы видели метод clickAndHold(), который кликает и удерживает веб-элемент на текущем положении курсора. Не важно, какой это элемент. Если же мы хотим работать с конкретным веб-элементом, мы должны сначала переместить курсор в соответствующую позицию и затем выполнить действие clickAndHold(). Чтобы не возиться с геометрией, WebDriver предоставляет разработчикам другой вариант или перегруженный метод clickAndHold(), который принимает на вход веб-элемент.
API синтаксис:
public Actions clickAndHold(WebElement onElement)
Входной параметр – веб-элемент, по которому следует щелкнуть и удержать. Как и во всех методах класса Actions, возвращаемое значение – экземпляр Actions.
Перепишем пример из предыдущего раздела:
public class ClickAndHold{
public static void main(String... args) { WebDriver driver = new FirefoxDriver();
driver.get("file://C:/Sortable.html");
WebElement three = driver.findElement(By.name("three")); Actions builder = new Actions(driver);
//Move tile3 to the position of tile2
builder.clickAndHold(three)
.moveByOffset(120, 0)
.perform();
}
}
Единственное изменение – мы удалили действие перемещения курсора к позиции (200, 20) и передали веб-элемент в метод clickAndHold() который позаботится об идентификации этого веб-элемента. Действие отпустить кнопку мыши на текущем месте
Противоположное действие – отпустить левую кнопку мыши.
API синтаксис метода release():
public Actions release()
Код:
public class ClickAndHoldAndRelease{
public static void main(String... args) { WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Sortable.html");
WebElement three = driver.findElement(By.name("three")); Actions builder = new Actions(driver);
//Move tile3 to the position of tile2
builder.clickAndHold(three)
.moveByOffset(120, 0)
.release()
.perform();
}
} Предыдущий код обеспечит, чтобы кнопка мыши была отпущена на заданном местоположении. Действие отпустить на другом веб-элементе
Это перегруженная версия метода release(). С ее помощью вы можете отпустить удерживаемый в данный момент веб-элемент в середине другого веб-элемента. Таким образом, нам не нужно вычислять смещение целевого веб-элемента сравнительно с удерживаемым веб-элементом.
API синтаксис:
public Actions release(WebElement onElement)
Входной параметр – целевой веб-элемент.
Код:
public class ClickAndHoldAndReleaseOnWebElement{ public static void main(String... args) {
WebDriver driver = new FirefoxDriver(); driver.get("file://C:/Sortable.html");
WebElement three = driver.findElement(By.name("three")); WebElement two = driver.findElement(By.name("two")); Actions builder = new Actions(driver);
//Move tile3 to the position of tile2
builder.clickAndHold(three)
.release(two)
.perform();
}
} Мы удалили весь код moveByOffset и добавили метод release(), который принимает на вход веб-элемент под названием two.
Вызов методов release() или release(WebElement) без вызова метода clickAndHold() приведет к неопределенному поведению. 0>0> |
|
|