Как перемещаться по вкладкам при помощи python и seleniumWD?

Здравствуйте! Искал информацию по данной проблеме. Натыкался только на jawa.

Ситуация такая. В процессе работы на вкладке, после нажатия на кнопку открывается 2 вкладки с документами в pdf. Фокус переключается на одну из новых вкладок. Как мне переместиться обратно на первую вкладку и продолжить работу в ней?

Я нашел пару методов

driver.switch_to_window(id_windows) - переход на окно
driver.window_handles - список всех окон
driver.close() - закрыть вкладку

С первыми двумя я не разобрался, не пойму что нужно подставлять - может вы приведете хороший пример? А если использовать driver.close() то закрывается именно первая вкладка (которая нужна). а не активная вкладка с pdf документом.

1 лайк

driver.window_handles - выводит список хэндлов (уникальный строковый идентификатор) всех открытых в данной сессии окон
driver.current_window_handle - выводит хэндл текущего окона, с которым работает драйвер (то окно, в которое идут все команды, в том числе и driver.close())

Для работы с другим окном, надо в него сначала переключится - driver.switch_to.window(handle)

Алгоритм такой:

  • запоминаем хэндл текущего окна
  • открываем новое окно
  • читаем хэндлы всех окон
  • переключаемся в то окно, хендл которого не совпадает с запомненным ранее
  • делаем что надо и закрываем окно
  • переключаемся обратно в то окно, хендл которого запомнили в самом начале (это важно, так как после закрытия окна, селениум сам туда не переключается и продолжает слать команды в никуда)
1 лайк

Выбор окна всё же лучше не привязывать к отцовскому хендлу. В селениуме должно быть что-то вроде getWindowTitle или getWindowUrl, ну в джаваскрипте точно есть, можно оттудова вызвать. И вот по этому значению сравнивать, в нужно ли вы окне или нет. Так надежнее, потому что первый же рекламный баннер, или попап с новостью или формой логина ломает ваш тест, внося ещё одно дополнительное окно на которое вы переключитесь впервую очередь.

1 лайк

Интересно, как вычитать урл, не переключаясь в другое окно?

for handle in driver.window_handles:
    if  driver.switch_to.window(handle).getWindowUrl == чё надо
        pass

В начале все же надо в него переключится ))
Ну и не лишним было бы еще и вейт поставить на появление нового окна.

У меня ситуация такая, что везде один и тот же тайтл и юрл. Просто у нас фронтэнд на Ext JS и там все делается внутри на одной странице.

Ничего что я в псевдокоде писал? Это алгоритм, а не реализация. И вейты это зло. Есть несколько разных способов их избежать.

qukobrist
Всегда есть что-то, за что можно зацепиться. Если это динамический JS, то можно ждать появления какого-то элемента на странице. Хотя зачем нужны две табы, чтобы изображать одну страничку - для меня загадка, но в целом у вас есть механизм переключения по табам/окнам описаный выше.

“И вейты это зло. Есть несколько разных способов их избежать.”
О, это интересно. Как можно избежать ожиданий?

Читая мануалы, самый верный

Это не ответ. У меня в мануалах написано, что без ожиданий совсем никак не обойтись. Интересно что у вас написано?

А я вобще ниче не знаю, из села я. Пишу че ни попаде где ни попаде. Бабка говорила, чтоба успяшным быть, галдеть надобно много. Так вот и галжу, ничяго не соображая в событиях браузера, ос, explicit и implicit waits, и навоз разбрасываю наподобии:

Я не в силах это распарсить. Мы вообще о чем говорим?
“И вейты это зло. Есть несколько разных способов их избежать.”
Как можно избежать вейтов, если твой код запускается на одной стороне, а приложение на другой?

ну ситуация такая - я нажал на кнопку “Купить” и тут же у меня открылся документ платежка.pdf в отдельной вкладке и я переместился в отдельную вкладку. Мне нужно теперь вернуться опять на ту же вкладку где и кнопка

Метод ysparrow.
Запишите хендл основного окна в переменную до выполнения цикла. После цикла просто switchTo.window(old_handle)

я знаю. что делаю не правильно, но я использую time.sleep(секунды). Просто потмоу, что не понимаю, какие задержки делают driver.implicitly_wait(секунды). У меня часто бывает, что не добирает символы в поле ввода или быстро перескакивает поле. Короче слипы лучше всего работают.

Я запомнил current_hendle

b = self.driver.current_window_handle
        print(b)

Я запомнил все hendle открытые

s = self.driver.window_handles
        print(s)

Получилось

CDwindow-a7997c10-0029-4cdd-b0c6-dc418b4354f4

И все 3

['CDwindow-a7997c10-0029-4cdd-b0c6-dc418b4354f4', 'CDwindow-f040580f-cc87-4136-a056-e3c6bb8076c9', 'CDwindow-073295d9-c553-48f9-8f67-18ee6212dda0']

Если я указываю каррентхэндл, то переключаюсь в него

driver.switch_to.window(CDwindow-a7997c10-0029-4cdd-b0c6-dc418b4354f4)

Выдает ошибку. Как мне переместиться на нужную мне вкладку?

‘CDwindow-a7997c10-0029-4cdd-b0c6-dc418b4354f4’ со скобками

Я здесь вынужден извиниться перед sparrow, так как работаю с кодом где wait == sleep, и под конец дня мой мозг вейты приравнял к слипам. Слипы зло, Слипы! waitFor - это гут.

Вот благодаря последнему комменту от qukobrist смог переключить разницу у себя в мозгу.

qukobrist:
Не надо слип. Есть более правильные способы:

http://www.seleniumeasy.com/selenium-tutorials/webdriver-event-listener-example

Представьте, что каждая сеекунда слипа, это 3 миллиарда операций, которые мог бы выполнить процессор вашего компьютера, но он этого не делает, просто хаотично переключаясь между остальными потоками.

3 лайка

implicitly_wait тут не помогут, копайте в сторону WebDriverWait и selenium.webdriver.support.expected_conditions — Selenium 4.9 documentation

1 лайк