Selenium java code review #1

Code review of Selenium java. Примеры говнокода из реальных проектов и примеры его улучшения. Не обязательно идеальные, но тем не менее лучшие )

Wrong way:

//Wait 15 min till e-Mail waiting time
logger.info("e-Mail sent out, wait 15 min till it will be on patrick@test.com");
Thread.sleep(900000);
logger.info("15 min left go check Mail");

Good way:

//check that e-mail was received
By searchButtonBy = By.xpath("//td/input[@name='searchbutton']");
By subjectBy = By.xpath("//a[contains(text(),'"+ emailSubject +"')]");
int count = driver.findElement(subjectBy).size();
int j = 1;
logger.info("Check e-mail every 10 sec. during 10 min.");
while ((count < 1) && (j < 60)) {
    // check e-mail during 3 min and every 10 sec.
    j++;
    Thread.sleep(10000);
    new driver.findElement(searchButtonBy).click();
    count = driver.findElements(subjectBy).size();
    logger.info(j +". number of emails -  " + count);
}
if (count < 1) throw new Exception("There is no e-mail, something went wrong.");

Selenium, java, timezone

Тест запускается в одной токе, сайт находится в другой. Обе эти точки могут произвольно изменяться. Но для корректной работы нужно всегда знать корректное время на сервере с сайтом, т.е на фронтенде.

Предлагаю такое решение:

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(«Europe zone: » + TimeZone.getTimeZone(«CET»));
System.out.println(«Local zone: » + TimeZone.getDefault());

int europeOffset = TimeZone.getTimeZone(«CET»).getOffset(System.currentTimeMillis());
int localOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis());

System.out.println(«Europe offset: » + amsOffset);
System.out.println(«Local offset: » + localOffset);
int delta = (europeOffset — localOffset) / 60000;
System.out.println(delta + » min»);

c.add(Calendar.MINUTE, delta);

Date currentDate = c.getTime();
System.out.println(«date today = » + currentDate);

Здесь «СЕТ» — часовой пояс на frontend. Его можно передавать как параметр, а можно и правильно хранить в файле property каждого сервера с которым может работать тест.

P.S. Да, летнее /зимнее время тут учтено!

Selenium, Java, время на Frontend

Проблема:
1. Тест может запускаться из разных часовых поясов — локально, на разных серверах с Jenkins.
2. Тест может проверять разные инстансы фронтенда — Demo, Staging, Production.
Всё это может находиться в разных часовых поясах

Задача: тест должен оперировать/определять время фронтенда с которым он работает.

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(«Europe zone: » + TimeZone.getTimeZone(«CET»));
System.out.println(«Local zone: » + TimeZone.getDefault());

int europeOffset = TimeZone.getTimeZone(«CET»).getOffset(System.currentTimeMillis());
int localOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis());

System.out.println(«Europe offset: » + amsOffset);
System.out.println(«Local offset: » + localOffset);
int delta = (europeOffset — localOffset) / 60000;
System.out.println(delta + » min»);

c.add(Calendar.MINUTE, delta);

Date currentDate = c.getTime();
System.out.println(«date today = » + currentDate);

Здесь в коде часовой пояс захардкожен. Правильно брать его из параметров фронденда. Но это уже сами ))).

Selenium и iframe

Хром в панели разработчика находит элемент по xPath, а Selenium не хочет по нему кликать и ругается, что элемент не найден.

Проблема в iframe. Selenium не видит элементы внутри iframe. Надо переключить фокус туда. Ну и не забыть потом вернуться.

driver.switchTo().frame(driver.findElement(By.xpath(«//iframe[@id=’iframeM’]»)));
driver.findElement(By.xpath(«//*[@id=’12345′]»)).click(); driverWrapper.switchTo().defaultContent();

Не успевает отработать Click

Исходные данные: автотест на java selenium. Столкнулся с ситуацией что после клика происходит долгая обработка данных и Selenium падает по таймауту. Перелопатил интернет, перепробовал все ожидания — явные, не явные и все другие включая банальную паузу:

            driver.manage().timeouts().setScriptTimeout(180, TimeUnit.SECONDS);
            driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);
            driver.manage().timeouts().pageLoadTimeout(180, TimeUnit.SECONDS);

Ничего из этого не помогает. Автотест висит на клике, не переходит к следующей команде, а по истечению времени ожидания — падает.

Решение проблемы пришло с неожиданной для меня стороны и оказалось, как и все гениальное ), простым.

try {
                    driver.findElement(By.xpath("//*[@id='a_do_import']")).click();
                } catch (Exception exception) {
                    logger.info("Exception was catch, is waiting 2 min.");
                    new Pause("120000").act(driver, context, reporter);
                    logger.info("Reload page.");
                    ...
}

Ловим и обрабатываем ошибку сами.

Определяем точное время с учетом часового пояса и летнего/зимнего времени

Ниже пример для средне европейского времени.

Calendar c = Calendar.getInstance();
boolean isSummer = TimeZone.getTimeZone(«ECT»).inDaylightTime(c.getTime());
if (isSummer) {
//Summer time
c.add(Calendar.MINUTE, -60);
} else {
//Winter time
c.add(Calendar.MINUTE, -120);
}

Обратите внимание, здесь не используется устаревший класс Date().