How to get multi page JMeter Webdriver timing - selenium

I've been using JMeter for quite a while but webdriver is new to me.
I'm trying to do some timings for a multi-page scenario and have a question.
I'm using JMeter webdriver sampler and HTMLunit:
Here is the scenario
1. Go to a web page http://162.243.100.234
2. Enter the word hello in the search box
3. Click on submit
What I want to get is:
1. How long it took to load the first page
2. How long it took from when I clicked on submit to when the results page was loaded
I have the following code which only gives me ONE sample timing.
How do I change it so I'll have two?
var pkg = JavaImporter(org.openqa.selenium)
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
var wait = new support_ui.WebDriverWait(WDS.browser, 5000)
WDS.sampleResult.sampleStart()
WDS.browser.get('http://162.243.100.234/')
var searchField = WDS.browser.findElement(pkg.By.id('s'))
searchField.click()
searchField.sendKeys(['hello'])
var button = WDS.browser.findElement(pkg.By.id('searchsubmit'))
button.click()
WDS.sampleResult.sampleEnd()
I tried adding another sampleStart and sampleEnd but got and error.
Do I need to use two samplers somehow?

Yep, you need to split your code into 2 pieces:
First Sampler:
WDS.sampleResult.sampleStart()
WDS.browser.get('http://162.243.100.234')
WDS.sampleResult.sampleEnd()
Second Sampler:
var pkg = JavaImporter(org.openqa.selenium)
WDS.sampleResult.sampleStart()
var searchField = WDS.browser.findElement(pkg.By.id('s'))
searchField.click()
searchField.sendKeys(['hello'])
var button = WDS.browser.findElement(pkg.By.id('searchsubmit'))
button.click()
WDS.sampleResult.sampleEnd()
Mention WDS.sampleResult.sampleStart() and WDS.sampleResult.sampleEnd() methods invocation
As per Using Selenium with JMeter's WebDriver Sampler guide
WDS.sampleResult.sampleStart() and WDS.sampleResult.sampleEnd()
captures sampler’s time and will track it. You can remove them, the
script will still work but you can’t get load time
Hope this helps

Related

Selenium webdriver : Not able to perform Keyboard actions like obj.sendKeys(Keys.chord(Keys.SHIFT, "m")); in Google Chrome

On a web page i have execute SHIFT+m from my keyboard for which i have used Action class but that step getting skipped every time in my code and the execution went to the next step.
Tried with both Action class and Robot class in Cucumber based framework using jUnit
I have tried
Actions obj = new Actions(driver);
obj.sendKeys(Keys.chord(Keys.SHIFT, "m"));
obj.build().perform();
Actions obj = new Actions(driver);
obj.sendKeys(Keys.SHIFT, "m");
I am using macbook pro m2 chip, java version = 17
my pom.xml file is:
I dont see the element where you perform the action to (target). You still need to specify the element I believe.
WebElement clickable = driver.findElement(By.id("clickable"));
new Actions(driver)
.moveToElement(clickable)
.sendKeys("abc")
.perform();

Web scraping with jsoup in Kotlin

I am trying to scrape this website as part of my lesson to learn Kotlin and Web scraping with jsoup.
What I am trying to scrape is the Jackpot $1,000,000 est. values.
The below code was something that I wrote after searching and checking out a couple of tutorials online, but it won't even give me $1,000,000 (which was what this code was trying to scrape).
Jsoup.connect("https://online.singaporepools.com/lottery/en/home")
.get()
.run {
select("div.slab__text slab__text--highlight").forEachIndexed { i, element ->
val titleAnchor = element.select("div")
val title = titleAnchor.text()
println("$i. $title")
}
}
My first thought is that maybe this website is using JavaScript. That's why it was not successful.
How should I be going about scraping it?
I was able to scrape what you were looking for from this page on that same site.
Even if it's not what you want, the procedure may help someone in the future.
Here is how I did that:
First I opened that page
Then I opened the Chrome developer tools by pressing CTRL+
SHIFT+i or
by right-clicking somewhere on page and selecting Inspect or
by clicking ⋮ ➜ More tools ➜ Developer tools
Next I selected the Network tab
And finally I refreshed the page with F5 or with the refresh button ⟳
A list of requests start to appear (network log) and after, say, a few seconds, all requests will complete executing. Here, we want to look for and inspect a request that has a Type like xhr. We can filter requests by clicking the filter icon and then selecting the desired type.
To inspect a request, click on its name (first column from left):
Clicking on one of the XHR requests, and then selecting the Response tab shows that the response contains exactly what we are looking for. And it is HTML, so jsoup can parse it:
Here is that response (if you want to copy or manipulate it):
<div style='vertical-align:top;'>
<div>
<div style='float:left; width:120px; font-weight:bold;'>
Next Jackpot
</div>
<span style='color:#EC243D; font-weight:bold'>$8,000,000 est</span>
</div>
<div>
<div style='float:left; width:120px; font-weight:bold;'>
Next Draw
</div>
<div class='toto-draw-date'>Mon, 15 Nov 2021 , 9.30pm</div>
</div>
</div>
By selecting the Headers tab (to the left of the Response tab), we see the Request URL is https://www.singaporepools.com.sg/DataFileArchive/Lottery/Output/toto_next_draw_estimate_en.html?v=2021y11m14d21h0m and the Request Method is GET and agian the Content-Type is text/html.
So, with the URL and the HTTP method we found, here is the code to scrape that HTML:
val document = Jsoup
.connect("https://www.singaporepools.com.sg/DataFileArchive/Lottery/Output/toto_next_draw_estimate_en.html?v=2021y11m14d21h0m")
.userAgent("Mozilla")
.get()
val targetElement = document
.body()
.children()
.single()
val phrase = targetElement.child(0).text()
val prize = targetElement.select("span").text().removeSuffix(" est")
println(phrase) // Next Jackpot $8,000,000 est
println(prize) // $8,000,000
Here is another solution for parsing a dynamic page with Selenium and jsoup.
We first get and store the page with Selenium and then parse it with jsoup.
Just make sure to download the browser driver and move its executable file to your classpath.
I downloaded the Chrome driver version 95 and placed it along my Kotlin .kts script.
System.setProperty("webdriver.chrome.driver", "chromedriver.exe")
val result = File("output.html")
// OR FirefoxDriver(); download its driver and set the appropriate system property above
val driver = ChromeDriver()
driver.get ("https://www.singaporepools.com.sg/en/product/sr/Pages/toto_results.aspx")
result.writeText(driver.pageSource)
driver.close()
val document = Jsoup.parse(result, "UTF-8")
val targetElement = document
.body()
.children()
.select(":containsOwn(Next Jackpot)")
.single()
.parent()!!
val phrase = targetElement.text()
val prize = targetElement.select("span").text().removeSuffix(" est")
println(phrase) // Next Jackpot $8,000,000 est
println(prize) // $8,000,000
Another version of code for getting the target element:
val targetElement = document
.body()
.selectFirst(":containsOwn(Next Jackpot)")
?.parent()!!
I only used the following dependencies:
org.seleniumhq.selenium:selenium-java:4.0.0
org.jsoup:jsoup:1.14.3
See the standalone script file. It can be executed with Kotlin runner from command line like this:
kotlin my-script.main.kts

Access submenu in Selenium using c#

Hi I am trying to access a submenu in selenium using c#. On my the website that I am testing the mouseover to the menu opens another submenu1,mouseover to submenu1 options open submenu2. I want to click on one of the submenu2 options. I tried to run below, everytime it throws an error of element not visible on custonboarding.Click();
Actions builder = new Actions(driver);
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
var hoverover = driver.FindElement(By.XPath("menu1"));
builder.MoveToElement(hoverover).Build().Perform();
var hoverover1 = driver.FindElement(By.XPath("submenu1));
builder.MoveToElement(hoverover1).Build().Perform();
var custonboarding = driver.FindElement(By.XPath("submenu2"));
custonboarding.Click();
Can someone help me out here?
It might take some time for the element to fully load. You can use explicit wait and ExpectedConditions to wait for the element to be visible
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
IWebElement custonboarding = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("submenu2")));
custonboarding.Click();
This will wait up to 5 seconds for the element to be visible.

Unable to perform click operation on elements with similar xpath styles in selenium

I've a web page with multiple download links(all pdf). I'm using selenium to test them (essentially to download all those pdfs). Given below is a spinet from the code:
//here's the list of all the elements
List<WebElement> elements = driver.findElements(By.xpath("//div[*]/ul/li/div/a[3]")); // total elements found: 278
for (WebElement we:elements) {
System.out.println(we.getText());
//custom written wait method
waitForElementPresent(By.xpath("//div[*]/ul/li/div/a[3]"),10); //executed 270 times
we.click(); // only the last item (278th) is actually clicked.
System.out.println("#click"); // this line is executed 278 times
}
It works fine, but only downloads the last pdf. Introducing a wait also doesnt work.
Out of interest, can you try it with this css selectors;
By.css("div>ul>li>div>a:nth-of-type(3)")
Try changing download settings - insert the below snippet before clicking on download links :
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir","C:\\test");
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/msword,application/x-rar-compressed,application/octet-stream,application/csv,text/csv,");
WebDriver driver = new FirefoxDriver(profile);
driver.get("any site");

Selenium WebDriver zoom in/out page content

How to change page zoom level in Selenium WebDriver?
I tried:
driver.Keyboard().pressKey(Keys.Control);
driver.Keyboard().pressKey(Keys.Add);
But it doesn't work.
Beware that Selenium assumes the zoom level is at 100%! For example, IE will refuse to start (throws an Exception) when the zoom level is different, because the element locating depends on this and if you changed the zoom level, it would click on wrong elements, at wrong places.
Java
You can use the Keys.chord() method:
WebElement html = driver.findElement(By.tagName("html"));
html.sendKeys(Keys.chord(Keys.CONTROL, Keys.ADD));
Use cautiously and when you're done, reset the zoom back to 100%:
html.sendKeys(Keys.chord(Keys.CONTROL, "0"));
C#
(since I realized C# bindings don't have the Keys.chord() method)
Or, you can use the Advanced User Interactions API like this (again, Java code, but it should work the same in C#):
WebElement html = driver.findElement(By.tagName("html"));
new Actions(driver)
.sendKeys(html, Keys.CONTROL, Keys.ADD, Keys.NULL)
.perform();
Again, don't forget to reset the zoom afterwards:
new Actions(driver)
.sendKeys(html, Keys.CONTROL, "0", Keys.NULL)
.perform();
Note that the naïve approach
html.sendKeys(Keys.CONTROL, Keys.ADD);
doesn't work, because the Ctrl key is released in this sendKeys() method. The WebElement's sendKeys() is different from the one in Actions. Because of this, the Keys.NULL used in my solution is required.
Here are two ways the zoom level can be altered with Java (one is for Chrome and the other is for Firefox):
Chrome
When using v̲e̲r̲s̲i̲o̲n̲ ̲3̲.̲3̲.̲1 of the Selenium Java Client Driver and C̲h̲r̲o̲m̲e̲D̲r̲i̲v̲e̲r̲ ̲2̲.̲2̲8, the following works (where the number in single quotes represents the zoom level to use; 1 = 100%, 1.5 = 150%, etc.):
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.body.style.zoom = '1.5'");
Firefox
The zoom level can be modified with the following:
1. The aforementioned Java Client Driver
2. G̲e̲c̲k̲o̲D̲r̲i̲v̲e̲r̲ ̲v̲0̲.̲1̲5̲.̲0
3. These classes:
java.awt.Robot
java.awt.event.KeyEvent
First of all, instantiate the Robot class:
Robot robot = new Robot();
This code causes the zoom level to decrease:
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_MINUS);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_MINUS);
This code causes the zoom level to increase:
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_EQUALS);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_EQUALS);
Python approach working for me, except you have to specify the zoom level:
driver.execute_script("document.body.style.zoom='zoom %'")
Have 'zoom%' = whatever zoom level you want. (e.g. '67%'). This works for Chromedriver, which doesn't seem to accept the send_keys commands.
Zoom in | Zoom out Feature on Windows
Zoom in
WebElement html = driver.findElement(By.tagName("html"));
html.sendKeys(Keys.chord(Keys.CONTROL, Keys.ADD));
Zoom out
html.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));
Zoom in | Zoom out Feature on MAC
Zoom in
WebElement html = driver.findElement(By.tagName("html"));
html.sendKeys(Keys.chord(Keys.COMMAND, Keys.ADD));
Zoom out
html.sendKeys(Keys.chord(Keys.COMMAND, Keys.SUBTRACT));
The most robust approach
Before you start with Internet Explorer and Selenium Webdriver Consider these two important rules.
The zoom level :Should be set to default (100%) and
The security zone settings : Should be same for all. The security settings should be set according to your organisation permissions.
How to set this?
Simply go to Internet explorer, do both the stuffs manually. Thats it. No secret.
Do it through your code.
Method 1:
//Move the following line into code format
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver","D:\\IEDriverServer_Win32_2.33.0\\IEDriverServer.exe");
WebDriver driver= new InternetExplorerDriver(capabilities);
driver.get(baseURl);
//Identify your elements and go ahead testing...
This will definetly not show any error and browser will open and also will navigate to the URL.
BUT This will not identify any element and hence you can not proceed.
Why? Because we have simly suppressed the error and asked IE to open and get that URL. However Selenium will identify elements only if the browser zoom is 100% ie. default. So the final code would be
Method 2 The robust and full proof way:
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver","D:\\IEDriverServer_Win32_2.33.0\\IEDriverServer.exe");
WebDriver driver= new InternetExplorerDriver(capabilities);
driver.get(baseURl);
driver.findElement(By.tagName("html")).sendKeys(Keys.chord(Keys.CONTROL,"0"));
//This is to set the zoom to default value
//Identify your elements and go ahead testing...
Hope this helps. Do let me know if further information is required.
Below snippet will set the browser zoom to 80%
String zoomJS;
JavascriptExecutor js = (JavascriptExecutor) driver;
zoomJS = "document.body.style.zoom='0.8'";
js.executeScript(zoomJS);
I know this is late, but in case if you don't want to use action class (or getting any errors, as I did) you can use pure JavaScript to do so.
Here is the code
((IJavaScriptExecutor) Browser.Driver).ExecuteScript("document.body.style.zoom = '70%';");
For Zoom In to 30%(or any other value you wish but in my case 30%) use
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.body.style.zoom = '30%';");
I am using Python 3.5.; I got the same problem as you. I thought you must use Chrome as browser.
I used PhantomJs to finally solve this problem:
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
browser = webdriver.PhantomJS()
browser.get('http://www.*.com')
print(browser.title)
c=browser.find_element_by_tag_name("body")
c.send_keys(Keys.LEFT_CONTROL+Keys.Add)`
you may use "Keys.chord" method for Zoom out and Zoom in
Zoom OUT
WebElement zoomPage = driver.findElement(By.tagName("html"));
zoomPage.sendKeys(Keys.chord(Keys.CONTROL, Keys.ADD))
when you are done with your work and want to reset browser back to 100% then use below code
If you want to click on any element, so before click event you may reset you browser window to 100 % after you may click on it.
zoomPage.sendKeys(Keys.chord(Keys.CONTROL, "0"));
You may user Java script code as well for Zoom OUT
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.body.style.zoom = '110%'");
Changing the zoom level through javascript execution is OK but it only apply to the first page displayed. The succeeding pages will return to 100% zoom level.
The best solution I found so far is to set the Chrome Options' device scale factor.
ChromeOptions options = new ChromeOptions();
options.addArguments("force-device-scale-factor=0.75");
options.addArguments("high-dpi-support=0.75");
WebDriver driver = new ChromeDriver(options);
Seems that approach proposed for C# doesn't work anymore.
Approach for C# that works for me in WebDriver version 2.5 is:
public void ZoomIn()
{
new Actions(Driver)
.SendKeys(Keys.Control).SendKeys(Keys.Add)
.Perform();
}
public void ZoomOut()
{
new Actions(Driver)
.SendKeys(Keys.Control).SendKeys(Keys.Subtract)
.Perform();
}
Using Robot class worked for me:
for(int i=0; i<3; i++){
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_MINUS);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_MINUS);
}
this will zoom out 3 times.
11-17-2017 Update
var html = page.FindElement(By.XPath("/html"));
html.SendKeys(Keys.Control + "0" + Keys.Control);
You can use Selenium's driver to execute a script that will zoom in or out for you.
Firefox
await driver.executeScript('document.body.style.MozTransform = "scale(3)"');
await driver.executeScript(
'document.body.style.MozTransformOrigin = "top"'
);
This will result in zooming in by 300% and will scroll to top.
Chrome
await driver.executeScript('document.body.style.zoom = "300%"');