Как упоминалось ранее, клавиши курсора генерируют три байта - и ключи, такие как home / end, даже генерируют четыре! Решение, которое я видел где-то, должно было позволить первому one-char read () следовать за тремя последующими односимволами с очень коротким таймаутом. Наиболее распространенные последовательности клавиш можно показать следующим образом:
#!/bin/bash
for term in vt100 linux screen xterm
{ echo "$term:"
infocmp -L1 $term|egrep 'key_(left|right|up|down|home|end)'
}
Кроме того, / etc / inputrc содержит некоторые из них с отображением readline. Итак, отвечая на исходный вопрос, вот отрезок из этого меню bash i 'просто взломать:
while read -sN1 key # 1 char (not delimiter), silent
do
# catch multi-char special key sequences
read -sN1 -t 0.0001 k1
read -sN1 -t 0.0001 k2
read -sN1 -t 0.0001 k3
key+=${k1}${k2}${k3}
case "$key" in
i|j|$'\e[A'|$'\e0A'|$'\e[D'|$'\e0D') # cursor up, left: previous item
((cur > 1)) && ((cur--));;
k|l|$'\e[B'|$'\e0B'|$'\e[C'|$'\e0C') # cursor down, right: next item
((cur < $#-1)) && ((cur++));;
$'\e[1~'|$'\e0H'|$'\e[H') # home: first item
cur=0;;
$'\e[4~'|$'\e0F'|$'\e[F') # end: last item
((cur=$#-1));;
' ') # space: mark/unmark item
array_contains ${cur} "${sel[@]}" && \
sel=($(array_remove $cur "${sel[@]}")) \
|| sel+=($cur);;
q|'') # q, carriage return: quit
echo "${sel[@]}" && return;;
esac
draw_menu $cur "${#sel[@]}" "${sel[@]}" "$@" >/dev/tty
cursor_up $#
done
WebDriver не является потокобезопасным. Я могу сослаться на Selenium FAQ
Q: Является ли WebDriver поточно-ориентированным?
blockquote>
A: WebDriver не поточно-ориентирован. Сказав это, если вы можете сериализовать доступ к базовому экземпляру драйвера, вы можете поделиться ссылкой более чем в одном потоке. Это не рекомендуется. С другой стороны, вы можете / можете / создать один экземпляр WebDriver для каждого потока.Не имеет значения, используется ли ваше решение в больших или малых проектах. Если вы хотите масштабировать свое решение, вы всегда можете использовать сетку Selenium для параллельного выполнения. Локальные объекты WebDriver не будут вашей проблемой. Заполнение памяти съедая экземпляры Chrome будет вашей проблемой.
Если вы хотите использовать только TestNG без каких-либо расширений, вам нужно обрабатывать веб-драйвер через ThreadLocal
private final ThreadLocal<WebDriver> driver = new ThreadLocal<>();
Драйверы следует создавать с помощью синхронизированных методов.
public synchronized WebDriver createDriver() {
return new ChromeDriver(options.getOptions());
}
@BeforeMethod(alwaysRun = true)
public void setupDriver(String browser) {
driver.set(CcreateDriver());
}
public synchronized WebDriver getDriver() {
return driver.get();
}
Вы также должны помнить, чтобы использовать потоки безопасные карты, списки и т. Д., Как concurentHashMap и т. Д. Это также применяется для Selenium Grid. Поэтому ThreadLocal также следует применять к RemoteWebDriver, поскольку он также не является поточно-ориентированным.
Это может произойти, так как thread-count
не на правильном месте. Согласно документации TestNG thread-count
должен быть в теге suite . Пожалуйста, используйте его, как указано ниже.
<suite name="My suite" parallel="methods" thread-count="5">
Проверьте документацию тестирования здесь:
http://testng.org/doc/documentation-main.html#parallel-running
Я бы предложил использовать расширение qaf TestNG , которое отвечает за управление драйверами, управление ресурсами и многое другое для автоматизации функциональных тестов веб, мобильных и веб-сервисов. С qaf ваш тестовый класс может выглядеть следующим образом:
public class NewTest extends WebDriverTestCase{
@Test()
public void method1() {
getDriver().get("https://www.google.com");
getDriver().findElement(By.name("q")).sendKeys("parallel");
getDriver().findElement(By.name("q")).sendKeys(Keys.ENTER);
}
@Test()
public void method2() {
getDriver().get("https://www.google.com");
//another improved way
WebElement ele = getDriver().findElement(By.name("q"));
ele.sendKeys("methods");
ele.sendKeys.submit();
}
@Test()
public void method3() {
getDriver().get("https://www.google.com");
//another way with qaf
WebElement ele = $("name=q");
ele.sendKeys("testng");
ele.sendKeys.submit();
}
}
Более того, вы можете сделать тестирование управляемым данными с использованием встроенных поставщиков данных.