Selenium - clicking on youtube links - selenium

I just tried to open the first search result of the youtube link.
Here is my code. Since the youtube results are in iFrame, I used SwitchTo.frame()method.
String browser = "Chrome";
WebDriver b = null;
if(browser.equals("Chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver_win32\\chromedriver.exe");
b = new ChromeDriver();
}
else if (browser.equals("firefox")) {
b = new FirefoxDriver();
}
b.get("http://www.youtube.com/");
b.findElement(By.xpath("//*[#id='masthead-search-term']")).sendKeys("selenium tutorial for beginner");
b.findElement(By.xpath("//*[#id='masthead-search-term']")).sendKeys(Keys.RETURN);
b.switchTo().frame("pyv-iframe"); //youtube search results are in iframe
//b.findElement(By.linkText("Selenium IDE Demo - Quick Beginner's Tutorial")).click();
b.findElement(By.xpath("//*[#id='search-results']/li[1]/div[2]/h3/a/span")).click();
While running this code it returns as
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element
at findElement By xpath. Please tell me what am I missing. Please see me as a newbie to Selenium.

I'm not sure why you are saying that the results are in an <iframe>... I'm not seeing an iframe. Here is your script using the getting started with selenium framework:
#Config(url="http://youtube.com")
public class YouTubeTest extends AutomationTest {
#Test
public void myTest() {
setText(By.id("masthead-search-term"), "selenium tutorial for beginner")
.click(By.id("search-btn"))
// navigate to a search result based on index
.click(By.cssSelector("ol#search-results > li:nth-child(X) a.yt-uix-tile-link"))
;
}
}
on the click(By.cssSelector you need to replace the X value with 1, 2, etc.. whatever the index of the link you want to click is.
(If you aren't using that framework you can easily translate the code and extract the selectors I use)

I did investigate on the Youtube page in Selenium IDE and it did get me these results:
driver = new FirefoxDriver();
baseUrl = "http://www.youtube.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(baseUrl + "/results?search_query=selenium&sm=3");
driver.findElement(By.id("masthead-search-term")).clear();
driver.findElement(By.id("masthead-search-term")).sendKeys("selenium");
driver.findElement(By.cssSelector("span.yt-ui-ellipsis-wrapper")).click();
Please note the last line: Thats where I clicked on the first search result. After investigating the Youtube page with Web Developer tools I realised that here is a iframe but it contains only some tracking code for AdSense (my guess)
General note: Always try to investigate with Selenium IDE first. It saved me from a lots of nightmares about my selenium code ;)

Related

Selenium couldn't find an element inside the iframe

I am creating an automated test cases for this page https://cloud.google.com/products/calculator in scope of my practical task using Selenium + Java.
At some point I've faced with a problem when the WebDriver couldn't find an element inside the iframe, even if in the previous test case I was able to interact with the elements of this iframe.
All my test cases are running one by one without closing the driver and each next test case can passed only if the previous test case passed as well.
Here is my GitHub repo:
https://github.com/SerhiiVeselov/hurt-me-planty.git
Here are my test cases:
#BeforeAll
public static void driverSetup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
mainPage = new MainPage(driver);
searchResultsPage = new SearchResultsPage(driver);
pricingCalculatorPage = new PricingCalculatorPage(driver);
fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofSeconds(2))
.ignoring(NoSuchElementException.class);
}
#Test
#Order(1)
#DisplayName("Search of the Pricing Calculator page")
public void openPricingCalculator() {
mainPage.openPage();
fluentWait.until(ExpectedConditions.visibilityOf(mainPage.getCookiesOkBtn()));
mainPage.closeCookiesPopUp();
mainPage.openSearchField();
mainPage.enterSearchRequest();
fluentWait.until(ExpectedConditions.visibilityOf(mainPage.getSuggestSearchResult()));
mainPage.clickSuggestSearchResult();
fluentWait.until(ExpectedConditions.visibilityOf(searchResultsPage.getSearchResultsTab()));
searchResultsPage.clickPricingCalculatorLink();
assertEquals("https://cloud.google.com/products/calculator", driver.getCurrentUrl());
fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(pricingCalculatorPage.getCloudSideFrame()));
fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt((pricingCalculatorPage.getMyFrame())));
}
#Test
#Order(2)
#DisplayName("Fill the Calculation Form")
public void fillCalculationForm() {
pricingCalculatorPage.enterNumberOfInstances();
pricingCalculatorPage.selectOperatingSystem();
pricingCalculatorPage.selectProvisioningModel();
pricingCalculatorPage.selectMachineType();
pricingCalculatorPage.checkAddGpuCheckBox();
pricingCalculatorPage.selectGpuType();
pricingCalculatorPage.selectGpuQuantity();
pricingCalculatorPage.selectLocalSsd();
pricingCalculatorPage.selectDatacenterLocation();
pricingCalculatorPage.addToEstimate();
fluentWait.until(ExpectedConditions.visibilityOf(pricingCalculatorPage.getTotalEstimatedCost()));
assertEquals("Instance type: n1-standard-8", pricingCalculatorPage.getInstanceTypeTest().getText());
}
#Test
#Order(3)
#DisplayName("Check the name of the Machine type")
public void verifyMachineType() {
assertEquals("Instance type: n1-standard-8", pricingCalculatorPage.getInstanceTypeTest().getText());
}
Here is the webpage for which I've created 2d and 3d test cases: https://cloud.google.com/products/calculator
page for automation in 2d and 3d test cases
So far, 1st and 2d test cases are passing and working as expected. But 3d test case is failing all the time cause the WebDriver couldn't find the element from the getInstanceTypeTest method:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//div[contains(text(), 'Instance type')]"}
Most of elements I interested in are located inside the same iframe (id=myFrame).
I have a selector for instanceTypeTest WebElement creared using xpath //div[contains(text(), 'Instance type')].
In 3d test case I want to check this field and get from it a text value to compare it with the value which was selected at the left form at https://cloud.google.com/products/calculator page.
I guess, after I filling the left form with data and clicking the 'ADD TO ESTIMATE' button something is happening with the iframes or the driver is loosing it's focus to the right frame.
I tried to add at the beginning of the 3d test case some code which should take driver back to the default web page content and then switch driver to outer iframe (cloudSideFrame) and after that - to inner iframe (myFrame):
driver.switchTo().defaultContent(); fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(pricingCalculatorPage.getCloudSideFrame())); fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt((pricingCalculatorPage.getMyFrame())));
It didn't help me. Driver still couldn't find Instance type field.
I can't understand why driver could find some elements inside the iframe even if it could find some others inside the same iframe.
Please help me to solve this problem.

Selenium: How to assert that image is displayed under a certain section of a webpage

I am attempting to write a test that is able to do the following:
1. Navigate to a website.
2. Navigate to a page under the menu.
3. Once in that page, assert that the image I want is displayed under a section labeled "SECTION".
Here is my code (approach 1):
public void test1() throws Exception {
WebElement compare_image = driver.findElement(By.linkText("URL link where the image is located"));
driver.get("website URL");
WebElement image = driver.findElement(By.cssSelector("cssSelector for image from FireFox -> inspect element -> copy CSS selector"));
assertEquals(image, compare_image); }
I am very new to Selenium and QA automation, so any detailed help would be appreciated as my google searches so far are coming up short. It is giving me an element not present exception for the findElement call, but I don't know why as I tried all the Bys I could get from inspect element.
Am I approaching this correctly? If not, what can I do differently?
If you want to check image is present or not under a section then you have to create a webelement for that section.
WebElement section= driver.findElement(By.xpath("//img(#class=‘Section')"));
Now create an image element under section element.
WebElement image= section.findElement(By.xpath("//img(#class=‘Test Image')"));
Now check image is exist or not.
boolean imagePresent = image.isDisplayed();
Now assert on boolean result.
assertTrue(imagePresent, “No image is exist”);
Note: Please take care of locators for section and Image as you didn’t provide Html for it. Code will work perfectly.

How to find element in frame in Selenium

I used below code for finding the element in the frame but I got the error
kindly explain by this framebyinedex, framebystring, framebywebelement:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Framebyindex
{
public static void main(String[] args)
{
WebDriver f1=new FirefoxDriver();
f1.get("http://spicareers.com/spicareers/");
f1.switchTo().frame(1);
f1.findElement(By.linkText(" .Net - Senior Developer ")).click();
}
}
The error is:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"link text","selector":" .Net - Senior Developer "}
Before you have to switch to the frame:
driver.get("http://spicareers.com/spicareers/");
WebElement frame= driver.findElement(By.xpath("//frame[#name='JRAMPSMainFrame']"));
driver.switchTo().frame(frame);
and after you could try with:
WebElement myEl= driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
myEl.click();
Finally, if you want to switch back:
driver.switchTo().defaultContent();
EDIT
The interested element is inside the iframe with name "JRAMPSMainFrame". If you inspect your html, you could notice this:
NoSuchElementException simply means that, the selenium did not detect a link with the text as you asked it.
I suggest you to work with use by.xpath to resolve it. To get the xpath of the element, take the below steps on your chrome, or firefox browser.
Right click on the element (here the link)
Click on inspect. It opens the inspect console (Elements tab) in your browser, and highlights the clicked element.
Right click on the element in the elements tab
Choose copy
Copy Xpath
In your code, replace By.linkText with By.xpath
Paste the value as an string into the xpath("you paste here")
Or simpler, watch this video
Seems like you have selected a wrong frame or the link text might contain more spaces.
Chrome developer tools is your best friend in this situation. Use it to find the element correctly and to identify the frame.
SELECT FRAME
Open the application in chrome.
Open developer tools
Click Console tab of developer tool
Select you frame from the drop down
In the above picture there is only one frame.
FIND ELEMENT
After selecting the frame, type $x("//a[normalize-space(.) = '.Net - Senior Developer']") to check your xpath.
$x("") is the function for checking xpath in browser.
Using the above mechanism find the frame and the element.
Cheers!
If you take a closer look at the HTML of http://spicareers.com/spicareers/ the WebElement with text as .Net - Senior Developer is within an <iframe> tag. So before accessing the intended WebElement we have to switch to the frame first either through the frame_name, frame_id or frame_index as follows:
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("http://spicareers.com/spicareers/");
driver.switchTo().frame("JRAMPSMainFrame"); //using "frame_name"
WebElement elem = driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
elem.click();
You can use this code, First enter into the frame using name locator and try to locate the career option then
Try this code, I have modified your code:
public class Framebyindex
{
public static void main(String[] args)
{
WebDriver f1=new FirefoxDriver();
f1.get("http://spicareers.com/spicareers/");
f1.switchTo().frame( f1.findElement(By.name("JRAMPSMainFrame")));
WebElement netCareer= f1.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]"));
netCareer.click();
}
}
By using:
https://github.com/nick318/FindElementInFrames
you can write following:
SearchByFramesFactory searchFactory = new SearchByFramesFactory(driver);
SearchByFrames searchInFrame = searchFactory.search(() -> driver.findElement(By.xpath("//*[contains(text(), ' .Net - Senior Developer ')]")));
searchInFrame.getElem().ifPresent(WebElement::click);

selenium span link li not working

I am new to selenium. I am practicing to write a test case on http://www.countdown.tfl.gov.uk. Below are the steps I followed:
a) I opened the browser to selenium Web Driver
b) Found the search text Box and enter H32 and clicked on search button to selenium.
Till this part it works fine.
Now on the page I am actually getting two records on the left side of the page under the search. I am actually trying to click on the first one i.e. "Towards Southall,Townhall" link. Nothing is happening.
Below is my code:
public class CountdownTest {
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver)
}
//open the countdowntfl page
private WebDriver openWebDriver(){
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.get("http://www.countdown.tfl.gov.uk");
return driver;
}
private void searchforBus(WebDriver driver,String search){
WebElement searchBox = driver.findElement(By.xpath("//input[#id='initialSearchField']"));
searchBox.sendKeys(search);
WebElement searchButton = driver.findElement(By.xpath("//button[#id='ext-gen35']"));
searchButton.click();
}
private void selectrouteDirection(WebDriver driver){
WebElement towardssouthallLink= driver.findElement(By.xpath("//span[#id='ext-gen165']']"));
((WebElement) towardssouthallLink).click();
}
}
Please help me.
Thanks.
Since you are getting NoSuchElement Exception now, you may try the following code with the usage of WebDriver explicit wait.
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement towardssouthallLink = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//*[#id='route-search']//li/span)[1]")));
towardssouthallLink.click();
Or WebDriver implicit wait
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("http://www.countdown.tfl.gov.uk");
Tips:
The search results need some time to be retrieved, so please use Explicit wait or Implicit wait.
Don't use locators like span[#id='ext-gen165'], they are ExtJs auto generated.
In this case, css selector can also be used: #route-search li:nth-of-type(1) > span
You aren't calling selectrouteDirection.
You probably want:
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver);
}
You also don't need to cast here:
((WebElement) towardssouthallLink).click();
It's already a WebElement anyway.
I found that id for those links are dynamically generated. ids are of the form 'ext-genXXX' where XXX is number which is dynamically generated hence varies each time.
Actually, you should try with linkText:
For 'Towards Southall, Town Hall'
driver.findElement(By.linkText("Towards Southall, Town Hall")).click
For 'Towards Hounslow, Bus Station'
driver.findElement(By.linkText("Towards Hounslow, Bus Station")).click
Here is a logic:
Get all elements which have id starts with 'ext-gen' & iterate over it & click on link with matching text. Following is Ruby code(sorry, I don't know Java well):
links = driver.find_elements(:xpath, "//span[starts-with(#id, 'ext-gen')]")
links.each do |link|
if link.text == "Towards Southall, Town Hall"
link.click
break
end
end

Tutorial or tips needed to perform a set of web admin tasks using Selenium(Beginner level query)

I'm looking at a few pointers /a tutorial or maybe even another question to help me with my task. I'm looking to automate a web admin task. What I would like to do is :
Login to an application.
Navigate to a particular menu.
Search for a particular item through a search bar.
If the item is displayed in the search items then click on a set of buttons on the UI and proceed with the task.
If the item is not displayed in the search results then continue searching till the item is displayed , and then perform step 4.
I have been able to perform up to step 3 using the selenium IDE plugin for Firefox. But I'm not quite sure how to proceed and where to incorporate the logic for steps 4 and 5. Do I use a programming language?(If yes, then how?)
You hit the limits of the IDE pretty quickly. The IDE doesn't incorporate logic, but it is good for quick and dirty automation tasks, figuring out locator id's, and helping people learn the basics of selenium. I would suggest checking out learning how to script in Selenium Webdriver. Documentation: http://seleniumhq.org/docs/03_webdriver.html
So for example if you're using Java (this was stolen from the documentation):
public class Selenium2Example {
public static void main(String[] args) {
// Create a new instance of the Firefox driver
WebDriver driver = new FirefoxDriver();
// And now use this to visit Google
driver.get("http://www.google.com");;
// Find the text input element by its name
WebElement element = driver.findElement(By.name("q"));
// Enter something to search for
element.sendKeys("Cheese!");
//Pseudocode
if(element.isDisplayed()){
// Now submit the form. WebDriver will find the form for us from the element
element.submit();
}
else{
// Check the title of the page
System.out.println("Page title is: " + driver.getTitle());
}
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().toLowerCase().startsWith("cheese!");
}
});
// Should see: "cheese! - Google Search"
System.out.println("Page title is: " + driver.getTitle());
//Close the browser
driver.quit();
}
}