How can I test context menu functionality in a web app? - selenium

I'm playing with a grails app that has a contextmenu (on right-click).
The context menu is built using Chris Domigan's jquery contextmenu plugin.
While the contextmenus do actually work, I want to have automated tests, and I can't work out how to do it.
I've tried Selenium 2.05a (ie. Webdriver), but there's no rightClick method.
I notice that HtmlUnit has a rightclick method, but I don't seem to be able to detect any difference in the DOM between before the click and after it.

Currently there's no right click method in WebDriver, there's an enhancement request opened for it - http://code.google.com/p/selenium/issues/detail?id=161
For now you can use keyboard shortcut Shift+F10 to simulate the right click on the element:
WebElement element = driver.findElement(....);
element.sendKeys(Keys.chord(Keys.SHIFT, Keys.F10));

While I'd like to be able to do it in Internet Explorer or Firefox as well, the main usage will be HtmlUnit. It's nice that the HtmlUnit HtmlElement has a rightClick() method, but unfortunately it's protected and so not accessible from the WebDriver wrapped HtmlUnitWebElement.
I wrote a hack to make it accessible, and so now I can call rightClick(), although it only works if it's running with HtmlUnit - not IE or FF.
// Needs to be in this package to get access to the element
package org.openqa.selenium.htmlunit;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
public class OpenHtmlUnitWebElement extends HtmlUnitWebElement {
// Provide a constructor, even though we don't really need it.
public OpenHtmlUnitWebElement(HtmlUnitDriver parent, HtmlElement element) {
super(parent, element);
}
// this is the method we really want.
public static HtmlElement using(HtmlUnitWebElement huwe) {
return huwe.element;
}
}
Now my (groovy) test looks like this:
import static org.openqa.selenium.htmlunit.OpenHtmlUnitWebElement.using
...
def itemWithContextMenu = driver.findElement(By.id('theId'))
if (itemWithContextMenu instanceOf HtmlUnitWebElement) {
using(itemWithContextMenu).rightClick()
def contextMenu = driver.findElement(By.id('jqContextMenu'))
assert ...
}

if you use Ruby with Capybara, this one should be useful:
module Capybara
module Node
class Element
def context_click
#session.driver.browser.action.context_click(self.native).perform
end
end
end
end

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.

Unable to handle disabled element using selenium when there is no disabled attribute present

I have tried using isEnabled() but because its not a button and there is no disabled attribute present it always returns me true.
I have pasted code by inspecting, Please help me out in this,
9:29 AM
Click on this to see the code
It seems like your class name update with the "disabled" text when its disabled. So you can try bellow method.
<<<<<<<<Imports>>>>>>>>
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
<<<<<<<<Code>>>>>>>>
//get class value of the element
attribute = WebUI.getAttribute(findTestObject('<<Element Locator>>'), 'class')
boolean isSubstringPresent(String subString, String fullString) {
return fullString.contains(subString)
}
//this will print true if the disabled text included in the class
println isSubstringPresent("disabled", attribute) // true
Mostly you can return correct boolean from above print. If it works use IF condition and plan your work.
If the above method not works I would like to suggest to run bellow Javascript in your browser and check its output.
document.getElementByClassName("sc-AxhUy irOhyl bigtix-session bigtix-session--available bigtix-session--disabled").disabled
If it works you can execute the same in your automation, however I'm not familiar with Katalon Studio and found that following code will work for you.
<<<<<<<<Imports>>>>>>>>
import org.openqa.selenium.WebDriver as WebDriver
import org.openqa.selenium.JavascriptExecutor as JavascriptExecutor
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
<<<<<<<<Code>>>>>>>>
WebDriver driver = DriverFactory.getWebDriver()
JavascriptExecutor js = ((driver) as JavascriptExecutor)
String disabledState = js.executeScript(‘sc-AxhUy irOhyl bigtix-session bigtix-session--available bigtix-session--disabled").disabled’)
print(disabledState)
As I can see in your attached image, there is one attribute aria-disabled = true, You can always check against that attribute for checking whether it is enabled or disabled.

How do I check if an element is present on a webpage?

I'm using BrowserFactory in selenium and not WebDriver. I would like to check if an element is present on the DOM. If yes click it, otherwise do something else. There should be a simple solution to it but I'm not using WebDriver. If I do use it, it opens a new browser window and does everything in that.
Can you try this method to verify if the element is present
public static void isElementPresent(WebElement element) {
//log.info("Checking if element is present");
if(element.isDisplayed();){
element.click();
}
}

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);

Find a selected radiobutton via Selenium/Webdriver

I'm using Selenium 2 (Webdriver) for automating tests on a webpage.
However I wonder if there is way to find out if a radiobutton is selected or not using webdriver framework?
I can find the element and click it by using Click() method.
I would like to test that it actually was set, or is that implicit done by the Click() method on IWebElement object?
(Using C# and NUnit)
You can determine if an element is selected by catching the element and then checking selected.
IWebElement thisElement = driver.FindElement(By.ID(//radiobutton id));
if(thisElement.Selected)
{
//do something here.
}
you can do this other ways but the .Selected is what you are looking for.
webDriver.findElement(By.className("radio")).click();
Boolean radio = webDriver.findElement(By.className("radio")).isEnabled();
if(radio.booleanValue()==true){
result.addPassedTestStepResult("user cannot uncheck the radiobutton");
}