Selenium to click Images link on Google and click first image - selenium

I have the below code. When I execute this,
Firefox opens - Expected
Go to Google.com - Expected
Keys in Pluralsight logo on searchbox - expected
I do not know what happens then I see the Google.com page with no text in searchbox.
However, when I put breakpoint and step in line by line I see it clicks Images. So, what is wrong when I execute it without breakpoints?
Another question I have is, once I am on the Images screen, how do I make my script click on the 1st image? I see the class name is rg_ic rg_i but I cannot use this as it has spaces. The ID keeps changing everytime. So, how can I click the 1st image? I commented it for now because I cannot get it to work.
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new FirefoxDriver();
driver.Url = "http://google.com";
var searchBox = driver.FindElement(By.Name("q"));
searchBox.SendKeys("Pluralsight logo");
searchBox.Submit();
var imageLink = driver.FindElement(By.LinkText("Images"));
imageLink.Click();
//var firstImage = driver.FindElements(By.ClassName("rg_ic"))[0];
//firstImage.Click();
}
}
}

the image id's are constant, and I ran a successful test using this (granted I'm using python, but the syntax is similar):
driver.get("http://google.com")
search_box = driver.find_element_by_name("q")
search_box.send_keys("Pluralsight logo")
search_box.submit()
time.sleep(4)
first_img = driver.find_element_by_id("dimg_1").click()
You have to provide time for the image to load. You could do this with an expected condition or just an explicit wait. Hope this helps.

Related

Allure generates a viewport screenshot. how to capture a screenshot of the entire document

I am working with Java, TestNG, Selenium and Allure.
And I want to attach the screenshot of 'entire page' in the case of test failure.
But when using 'getScreenshotAs()' method, it attaches only the 'visible viewport' screenshot in the report. partially successful :)
#Attachment(value="Page Screenshot", type="image/png")
public byte[] saveScreenshotPNG(WebDriver driver) {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
And I am not very sure if AShot from ru.yandex.qatools could be helpful here,
As it returns Screenshot not Byte[].
This should capture the whole page:
Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(2000)).takeScreenshot(driver);
BufferedImage image = screenshot.getImage();

The element is obscured(Server did not provide stack information) automation in edge browser with selenium

org.openqa.selenium.WebDriverException: Element is obscured (WARNING: The server did not provide any stacktrace information).
This code is working fine for chrome and firefox but not with edge browser.
`public class Login {
public WebDriver driver;
By userName = By.id("ctl14_UserName");
By password = By.id("ctl14_Password");
By login = By.id("ctl14_LoginButton");
public Login(WebDriver driver) {
this.driver = driver;
}
// Set password in username textbox
public void setUserName(String strUserName) {
driver.findElement(userName).sendKeys(strUserName);
}
// Set password in password textbox
public void setPassword(String strPassword) {
driver.findElement(password).sendKeys(strPassword);
}
public void clickMyaccount(){
driver.findElement(myAccount).click();
}
// Click on login button
public void clickLogin() {
driver.findElement(login).click();
}
}
//Test class
public class AdminLogin extends BaseForDifferentLogins {
Login objLoginAdmin;
#Test(priority=0)
public void login() throws InterruptedException{
objLoginAdmin=new Login(driver);
objLoginAdmin.clickMyaccount();
Thread.sleep(3000);
objLoginAdmin.setUserName("superuser1");
objLoginAdmin.setPassword("superuser1");
Thread.sleep(3000);
objLoginAdmin.clickLogin();
Thread.sleep(3000);
}
}`
Instead of using webElement.click() you can try to build Actions with click and do perform. Had the same issue on Edge and that did the trick for me:
Actions actions = new Actions(webDriver);
actions.click(webElement).perform();
I have encountered the issue and tried several things to solve it:
enabled EdgePageLoadStrategy.Normal - did not help;
disabled the "save your password?" bubble. - did not help;
normalized the zoom level to 100% - bingo / eureka. This solved the issue.
My test script is a bit more performance-oriented, so I had no desire to add additional objects / capabilties / options. If you want your test to be more deployable add registry editing capabilities to your selenium script. This can be a starter: http://www.winhelponline.com/blog/microsoft-edge-disable-zoom-reset-zoom-level-every-start/
I encountered the same issue on the Edge browser.
It was difficult to figure out what was actually wrong, since the issue seemed to appear/disappear from time to time in my case.
So at some point I decided to contact MS and created this ticket question
Here Steven K mentioned that the obscured element error is most likely due to zoom level not being at 100% So I checked and indeed it was at 125% for some reason.
After I set it back to 100% the issue was resolved for me.
browser.send_keys [:control, '0']
I know this is a ruby+watir example, but I'm sure there is a similar Java trick for this.
I have also encountered this problem while testing Angular with Protractor in Microsoft Edge.
What finally helped me was combining two workarounds:
Set browser zoom value to 100% explicitly in beforeEach function:
browser.actions().keyDown(protractor.Key.CONTROL).sendKeys('0')
.keyUp(protractor.Key.CONTROL).perform();
Do click through browser actions:
browser.actions().mouseMove(yourElementThatIsNotActuallyObscured).click().perform();
Resetting Zoom level to 100% will fix the issue.
public void clickUntillNotObsecured(WebElement elementToClick) {
boolean obsecuredThrown = true;
int c=0;
while (obsecuredThrown && c<30) {
try {
clickOnElement(elementToClick);
obsecuredThrown = false;
} catch (WebDriverException e) {
obsecuredThrown = true;
}
c++;
}
}
You can perform the task with the Action chains in the python specially with Edge browser:
from selenium.webdriver import ActionChains
actionChains = ActionChains(driver)
button_xpath = '//xapth...'
button = driver.find_element_by_xpath(button_xpath)
actionChains.move_to_element(button).click().perform()
But sometimes Action chain does not finds the DOM element. Hence better option to use execute_script in following way which is compatible with all browsers:
button_xpath = '//xapth...'
button = driver.find_element_by_xpath(button_xpath)
driver.execute_script("arguments[0].click();", button)
Even I faced same problem today running tests on Edge, But when I observed the problem, after which step it's failing just check it up, after that step give a time delay of 5 to 10 seconds, by doing this it solved my problem. And i got the same error many times while running in Edge at different part of my program, i just added time delay at all those steps, it solved my problem and now test successfully running on EDGE.
I added delay by using
Thread.sleep(5000);
just try this, if it doesn't work for you, I found one other solution if it's failing at the time of clicking, that is perform click operation using javascript.
WebElement element = driver.findElement(By.id("gbqfd"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
This solution I got from
https://softwaretestingboard.com/qna/363/word-around-for-edge-driver-click
https://softwaretestingboard.com/qna/745/excpetion-selenium-webdriverexception-element-obscured
First one worked for me.

How to make Selenium WebDriver wait for page to load when new page is loaded via JS event

I'm working on automating a site which has a number of links which load new pages via a JS event. Basically, there are elements which are clickable, clicking on one causes some JavaScript to run and this leads to a form being submitted and routing to a new page.
Now if these were just standard HTML links there would be no problem as Selenium is smart enough to tell that there's a new page coming and to wait to do things. But as good as it is, Selenium can't tell that the clicks in this instance are leading to new pages to load so it doesn't wait and just keeps going. As such it doesn't wait for the new page, tries to find elements which aren't there and my tests all fail. Bummer.
As a temporary solution I'm just pausing the program for three seconds like so:
oldPageDriver.clickThatButton();
try {
Thread.sleep(3000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
newPageDriver = new NewPageDriver(driver);
newPageDriver.doStuffOnNewPage();
And this works, sort of. I don't like it because it's "hacky," and just interrupting the program instead of doing something smarter. Because the delay is hard coded at three seconds I get failures if the link is working but just slow. I've considered something like an implicit wait but that accomplishes the same thing and I've not found a solid, workable answer in Java anywhere after a considerable amount of looking.
So, can anyone suggest a way around this? Specifically, how to make Selenium know that a new page is expected and to wait until it's available?
The wait for the document.ready event is not the entire fix to this problem, because this code is still in a race condition: Sometimes this code is fired before the click event is processed so this directly returns, since the browser hasn't started loading the new page yet.
After some searching I found a post on Obay the testing goat, which has a solution for this problem. The c# code for that solution is something like this:
IWebElement page = null;
...
public void WaitForPageLoad()
{
if (page != null)
{
var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
}
var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));
page = driver.FindElement(By.TagName("html"));
}
`
I fire this method directly after the driver.navigate.gotourl, so that it gets a reference of the page as soon as possible. Have fun with it!
Explicit waits are what you need;
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
You can directly add this to your test or you may want to DRY it up, especially if there is a common wait expectation such as the disappearance of a spinning icon.
You could extend the click method to always wait after clicking or if following page objects, add a wait_until_loaded method to a base page class. There many other valid approaches but dependent on how the AUT is implemented
Simple ready2use snippet, working perfectly for me
static void waitForPageLoad(WebDriver wdriver) {
WebDriverWait wait = new WebDriverWait(wdriver, 60);
Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {
#Override
public boolean apply(WebDriver input) {
return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
}
};
wait.until(pageLoaded);
}

Create FullPage Screenshot WebDriver

Does someone knows a way to create full page screenshots using WebDriver?
I want if one of my tests fails to create a FULL PAGE (even the not visible part on the screen) screenshot before the browser close and save it on share location.
Also, if it is possible I want to output the result to Jenkins Console log.
Thanks!
You can use the following extension for Firefox: https://addons.mozilla.org/nl/firefox/addon/fireshot/
You can find its javascript code in %APPDATA%\Mozilla\Firefox\Profiles\
The extensions provide the ability to copy the screenshot to the clipboard.
You can use its JS methods to perform the screenshot. After that, you can retrieve the image from the clipboard and save it to as a file on shared location.
Image image = default(Image);
if (Clipboard.GetDataObject() != null)
{
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.Bitmap))
{
Image image = (Image)data.GetData(DataFormats.Bitmap,true);
image.Save("image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
Console.WriteLine("The Data In Clipboard is not as image format");
}
}
else
{
Console.WriteLine("The Clipboard was empty");
}
string newImageName = string.Concat(#"C:\SampleSharedFolder\", Guid.NewGuid());
image.Save(newImageName );
Console.WriteLine("Image save location: {0}", newImageName);
Once you have populated the result to Console it is really easy to output it back to Jenkins. You can find more in my article: http://automatetheplanet.com/output-mstest-tests-logs-jenkins-console-log/
You can use Snagit to perform full page screenshots. More information here: https://www.techsmith.com/tutorial-snagit-documentation.html
First you need to start the Snagit server and then follow the documentation.

Click then CTRL Click not working with selenium-java 2.39 + Firefox 26

I'm facing this issue since some days now but didn't manage to overcome it trying different ideas.
Problem description: I wanna select a line in a table (GWT CellTable), perform some actions (which are my application specific) on it and then unselect back the line.
The line never gets unselected.
I'm quite new to selenium And I don't know if someone else has run into same problem and if there is a workaround to it. Thanks in advance
Code:
#Test
#SuppressWarnings("serial")
public void testClearEventCodes(){
refreshBrowser();
testWEHSearch();
WebContext faresContext = rootContext.gotoId(Strings.WEH_FARES_TABLE);
//INITIALLY HOT AND EVENT FARE
assertTrue("Y N N N N".equals(faresContext.gotoTableCell(1, 15).getText()));
assertTrue("CHINAYEAR".equals(faresContext.gotoTableCell(1, 16).getText()));
checkColorCodes(new HashMap<String, String[]>(){
{
put(getFareKey("GMP", "PAR", "KE", "0004", "K001", "OW", "Public"), new String[]{"1", COLOR_CODE_HOT_AND_EVENT_FARE});
}
});
faresContext.gotoTableRow(1).getElementWebContext(1).click();
rootContext.gotoId(Strings.WEH_CLEAR_EVENT_CODES_BUTTON).click();
faresContext.gotoTableRow(1).getElementWebContext(1).ctrlClick();
//ENSURE ALL EVENT CODES ARE CLEARED
assertTrue("".equals(faresContext.gotoTableCell(1, 16).getText()));
checkColorCodes(new HashMap<String, String[]>(){
{
put(getFareKey("GMP", "PAR", "KE", "0004", "K001", "OW", "Public"), new String[]{"1", COLOR_CODE_HOT_FARE});
}
});
}
And bellow is the method to CTRL CLICK the line:
/**
* Holds Control key and Clicks on current element.
*/
public void ctrlClick() {
Actions actionBuilder = new Actions(driver);
actionBuilder.keyDown(Keys.CONTROL).click(getSingleElement()).keyUp(Keys.CONTROL);
org.openqa.selenium.interactions.Action action = actionBuilder.build();
action.perform();
}
Your problem might be related to the new Firefox feature in which display settings are now taken into account. You can try changing the display settings for your computer to 100% and try again.
https://code.google.com/p/selenium/issues/detail?id=6774