I couldn't click the select dropdown on the website - selenium

I couldn't click the depart, arrvie dropdown menu form
https://m.flyscoot.com/search
I tried to use Xpath to click them, But I got no luck:
#driver.find_element(:xpath, "//~~~~~" ).click
And is there any way to let me fill the date value manually.
It's impractical to click the date by mouse, if I want to click the whole year.
The more practical solution is generating dates of whole year then fill it in, but I could't get it with selenium firefox driver.
No luck by xpath with contains method:
#driver.find_element(:xpath, "//*[contains(text(),'Departure Airport')]")
NoSuchElementError: Unable to locate element:
[4] pry(#)> arrival = #driver.find_element(:xpath, "//[contains(text(),'Departure Airport')]")
Selenium::WebDriver::Error::NoSuchElementError: Unable to locate element: {"method":"xpath","selector":"//[contains(text(),'Departure
Airport')]"}
from [remote server] file:///var/folders/6d/th4jpm90n1cx8h2l3kr49fr0000gn/T/webdriver-profile20150612-45453-15z20qu/extensions/fxdriver#googlecode.com/components/driver-component.js:10271:in
`FirefoxDriver.prototype.findElementInternal'
webdriver
➜ workspace gem list selenium-webdriver
*** LOCAL GEMS ***
selenium-webdriver (2.45.0)

To get departure you could use(other ways too but I dont know what your source code so grabbing at strings here):
arrival = find_element_by_xpath("//*[contains(text(),'Departure Airport')")
departure find_element_by_xpath("//*[contains(text(),'Arrival Airport')")
As for setting the date, I would need to see your page source code. I would imagine that this could be accomplished using either straight JS, or Jquery with the driver.execute_script('script here') command.

Use below code to select airport:
driver.get("https://m.flyscoot.com/search");
// click on departure airport
driver.findElement(By.xpath("//div[#id='departureAirport-button']"))
.click();
// Select any of option from the list of airports,Here i m selecting "sydney"
driver.findElement(
By.xpath("html/body/div[6]/div/div[2]/div/div[3]/div/div/div/div/div[2]/div[1]/div/div[1]/div[5]/div"))
.click();
//Click on done
driver.findElement(By.xpath("//div[text()='Done']")).click();
And this is the code to select Date:
// Click on Departure Date
driver.findElement(By.xpath("//input[#id='date-depart-display']"))
.click();
// select date by clicking on particular date,Here i m selecting today's
// date.
driver.findElement(
By.xpath(".//*[#id='ui-datepicker-div']/div[1]/table/tbody/tr[2]/td[6]/a"))
.click();

First of all, wait for the departure dropdown to be visible before interacting with it.
Also, use the Select abstraction and selectByVisibleText() (Java):
wait = WebDriverWait(driver, 10);
WebElement departure = wait.until(ExpectedConditions.visibilityOfElementLocated(By.ID("departureAirport")));
Select departureSelect = new Select(select);
departureSelect.selectByVisibleText("Hong Kong (HKG)");
WebElement arrival = driver.findElement(By.ID("arrivalAirport"));
Select arrivalSelect = Select(arrival);
arrivalSelect.selectByVisibleText("Melbourne (MEL)");
The same logic in Python:
from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("https://m.flyscoot.com/search")
wait = WebDriverWait(driver, 10)
departure = wait.until(EC.visibility_of_element_located((By.ID, "departureAirport")))
departure = Select(departure)
departure.select_by_visible_text("Hong Kong (HKG)")
arrival = Select(driver.find_element_by_id("arrivalAirport"))
arrival.select_by_visible_text("Melbourne (MEL)")

I tried this code, it partially works (at least the date is getting selected), But the selection on departure airport is not, I am still wondering why, Please see if this gives u any start. Mean while i shall get back if get some solution.
Driver.navigate().to("https://m.flyscoot.com/search");
Driver.findElement(By.id("departureAirport")).click();
Select Element = new Select(Driver.findElement(By.id("departureAirport")));
Element.selectByVisibleText("Singapore (SIN)");
Driver.findElement(By.id("date-depart-display")).click();
Thread.sleep(10);
Driver.findElement(By.xpath("//*[#id='ui-datepicker-div']/div[1]/table/tbody/tr[3]/td[4]/a")).click();

Related

Selenium and non select dropdown list

Do you know if it was possible to click with selenium on a non select dropdown list?
I need to interact with this site : https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/projects-results
And click on the "Filter by programme" and after scraping return to the 1st page.
Drop Down Navigation
Elements within a dropdown list are typically hidden until the dropdown is initiated. Knowing this, the dropdown must be clicked on before clicking on any of the elements within the list. See below code for basic example:
from selenium import webdriver
driver = webdriver.Chrome()
dropdown_list = driver.find_element_by_xpath("XPATH_OF_DROPDOWN_LIST")
dropdown_list.click()
dropdown_element = driver.find_element_by_xpath("XPATH_OF_DROPDOWN_ELEMENT")
dropdown_element.click()
WebDriverWait
For a more advanced and better performing example, I would recommend the implementation of WebDriverWait as there sometimes is a lag between the elements of the dropdown list becoming available:
dropdown_element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "XPATH_OF_DROPDOWN_ELEMENT")))
Additional Resource
For those unfamiliar, the difference between time.sleep and WebDriverWait is that time.sleep will always wait N number of seconds where N is time.sleep(N). WebDriverWait however, will wait up to N seconds where N is WebDriverWait(driver, N). Meaning if WebDriverWait variable is set to 10 seconds, but the element becomes available in 2, the driver will perform the action in the 2 seconds and move onto the next command. But if the element takes longer than 10 seconds to show up, the program will throw a timeout exception.
The Filter by programme dropdown list opens up on clicking on the <label> element.
Solution
To click and expand the dropdown list you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH:
driver.get("https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/projects-results")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.wt-cck-btn-add"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[text()='Select a Programme...']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:

Login successfully but HTML element not found

I am learning web scraping with Selenium for Finance team project. The idea is:
Login to HR system
Search for Purchase Order Number
System display list of attachments
Download the attachments
Below are my codes:
# interaction with Google Chrome
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# specify chromedriver location
PATH = './chromedriver_win32/chromedriver.exe'
# open Google Chrome browser & visit Purchase Order page within HRIS
browser = webdriver.Chrome(PATH)
browser.get('https://purchase.sea.com/#/list')
< user input ID & password >
# user interface shows "My Purhcase Request" & "My Purchase Order" tabs
# click on the Purchase Order tab
try:
po_tab = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.LINK_TEXT, "My Purchase Orders"))
)
po_tab.click()
except:
print('HTML element not found!!')
# locate PO Number field and key in PO number
try:
po_input_field = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "input-field"))
)
po_input_field.send_keys(<dummy PO num#>) ## any PO number
except:
print("PO field not found!!")
# locate Search button and click search
try:
search_button = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.LINK_TEXT, "Search"))
)
search_button.click()
except:
print("Search button not found!!")
I stuck at the step # click on the Purchase Order tab and following steps.
I can find the elements but I can see error after executing the py script. The most interesting part is....I can do it perfectly in Jupyter Notebook.
Python Script Execute Error
Here are the elements after inspection screens:
Purchase Orders tab
PO Number input field
Search button
See you are using presence_of_element_located which is basically
""" An expectation for checking that an element is present on the DOM
of a page. This does not necessarily mean that the element is visible.
locator - used to find the element
returns the WebElement once it is located
"""
What I would suggest to you is to use element_to_be_clickable
""" An expectation for checking that an element is present on the DOM of a
page and visible. Visibility means that the element is not only displayed
but also has a height and width that is greater than 0.
locator - used to find the element
returns the WebElement once it is located and visible
so, in your code it'd be something like this :
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, "My Purchase Orders"))).click()
Also, we could try with different locators if this does not work, locators like CSS, XPATH. But I'll let you comment first if this works or not.
The first error in your log is HTML element not found! You are performing a click before element is visible on DOM. Please try below possible solutions,
Wait till element is visible then perform click operation.
EC.visibility_of_element_located((By.LINK_TEXT, "My Purchase Orders"));
If still you are not able click with above code then wait for element to be clickable.
EC.element_to_be_clickable((By.LINK_TEXT, "My Purchase Orders"));
I would suggest to create reusable methods for actions like click() getText() etc.

unable to locate elements in popup-window though switched focus to it, selenium

Tried to practice selenium on indeed.ca. The following describes my steps:
Openeded 'indeed.ca'
Typed 'IT support' in text area for searching
clicked on first job among the group of published jobs
clicked on "Apply Now' button,
a window-pop has come which has the fields to enter data relevant to labels like 'First Name', 'Last Name', 'Email' and a button 'choose file' to upload a resume.
After I switched the driver focus to 'window-pop', I am unable to locate elements.
Here are all the links used:
https://www.indeed.ca/
https://www.indeed.ca/jobs?q=it+support&l=Toronto%2C+ON (with search criteria IT SUPPORT)
https://www.indeed.ca/jobs?q=it%20support&l=Toronto%2C%20ON&vjk=837c0cbbf26a68a7 (link for the window after clicking first option in the jobs list)
I shared the screen-shot for window-pop after clicking on 'Apply Now'
Try this
The fields are inside nested iframes.
driver.switch_to_frame(driver.find_element_by_id('indeed-ia-1532701404288-0-modal-iframe'))
driver.switch_to_frame(driver.find_element_by_tag_name('frame'))
first_name = driver.find_element_by_id('input-applicant.name')
you can use this code, after clicking on Apply Now button :
There are two iframes , in order to interact with newly opened pop up, you will have to switch to both of the frames.
Code :
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path = r'D:/Automation/chromedriver.exe')
driver.maximize_window()
driver.get("https://www.indeed.ca/jobs?q=it%20support&l=Toronto%2C%20ON&vjk=837c0cbbf26a68a7")
wait = WebDriverWait(driver, 10)
apply_now = wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Apply Now']/ancestor::a")))
apply_now.click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"div.indeed-apply-bd>iframe")))
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[src^='https://apply.indeed.com/indeedapply/resumeapply?']"))
Name = wait.until(EC.element_to_be_clickable((By.ID, "input-applicant.name")))
Name.send_keys("Vijay")

Scrolling through pages with Python Selenium

I have written a python script that aims to take data off a website but I am unable to navigate and loop through pages to collect the links. The website is https://www.shearman.com/people? The Xpath on the site looks like this below;
ul class="results-pagination"
li class/a href onclick="PageRequest('2', event)"
When I run the query below is says that the element is not attached to the page;
try:
# this is navigate to next page
driver.find_element_by_xpath('//ul[#class="results-pagination"]/li/[#onclick=">"]').click()
time.sleep(5)
except NoSuchElementException:
break
Any ideas what I'm doing wrong on this?
Many thanks in advance.
Chris
You can try this code :
browser.get("https://www.shearman.com/people")
wait = WebDriverWait(browser, 30)
main_tab = browser.current_window_handle
navigation_buttons = browser.find_elements_by_xpath('//ul[#class="results-pagination"]//descendant::a')
size = len(navigation_buttons )
print ('this the length of list:',navigation_buttons )
i = 0
while i<size:
ActionChains(browser).key_down(Keys.CONTROL).click(navigation_buttons [i]).key_up(Keys.CONTROL).perform()
browser.switch_to_window(main_tab)
i=i+1;
if i >= size:
break
Make sure to import these :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
Note this will open each link in new tab. As per your requirement you can click on next button using this xpath : //ul[#class="results-pagination"]//descendant::a
If you want to open links one by one in same tab , then you will have to handle stale element reference as once you will be moved out from main page , all element will become stale.

Selenium WebDriver auto populate value from drop down

Could you please help me for finding an element in webdriver:
Suppose we have two drop downs one is client and second facility. Also, without selecting client we cannot select facility as its disabled.
We've selected client value from drop down.
Now I've written a script for a new tab.
After that, I've to find facility field through ID but it shows element is not found, then could you please help me for the same?
..
Attached is the screen shot for your reference.
Could you please check?
Continue with previous question Select options from Autopopulate text boxes using Selenium webdriver
When you are using same cssSelector second time, it locates first dropdown element which is invisible at that time. you need to use more specific locator as below using label text :-
WebElement facility = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("facility")))
facility.sendKeys("Ho")
List<WebElement> facilityOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Ordering Location']]/ul[#class = 'typeahead dropdown-menu']//a")))
facilityOptions.get(0).click()
Full working example code :-
driver.get("https://bioceptbetaweb.azurewebsites.net/Account/Login");
driver.manage().window().maximize()
WebDriverWait wait = new WebDriverWait(driver, 60)
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username"))).sendKeys("ajay.kumar#technossus.com");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("password"))).sendKeys("Ajay#123");
wait.until(ExpectedConditions.elementToBeClickable(By.id("btn-Login"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Place a New Order"))).click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loaderDiv")));
//this sleep is required because after invisibility of loader focus goes to first input which is Requisition Number
//If you are filling form from first input no need to for this sleep
//if you want to input directly to client field need to sleep to avoid focus first
Thread.sleep(3000);
WebElement client = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("client")));
client.sendKeys("Ho");
List<WebElement> dropdownOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Client']]/ul[#class = 'typeahead dropdown-menu']//a")));
dropdownOptions.get(0).click();
WebElement facility = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("facility")));
facility.sendKeys("Ho");
List<WebElement> facilityOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Ordering Location']]/ul[#class = 'typeahead dropdown-menu']//a")));
facilityOptions.get(0).click();