I have recently started working on UI testing and was wondering if there is any tool to figure out the time it takes to load the UI page to load in browser including the server response time ( i mean total browser time from request send till page load ).
I know that firebug/developer tools can be used to find it manually but is there any other way of doing it. Using selenium, i could use firefox driver and find out the time it takes to get the page and report that time, but i am not sure if it is the correct time.
A few words about the solution:
We will take help of Google Chrome browser for our reference. As we know when a page loads completely the browser returns Document.ReadyState as Complete to Selenium. That's when Selenium executes the next line of code. We will start the timer and start loading the webpage. When ever the document.readyState will be set to complete we will stop the timer. Here is the Selenium-Java code block:
package demo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Q_44643596_measurement_application_load {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 30);
long start = System.currentTimeMillis();
driver.get("https://stackoverflow.com/");
boolean pageLoaded = wait.until(ExpectedConditions.jsReturnsValue("return document.readyState")).equals("complete");
long finish = System.currentTimeMillis();
System.out.println("Page has loaded? " + pageLoaded);
long totalTime = finish - start;
System.out.println("Total Time (in Milli Seconds) for page load - "+totalTime);
}
}
Related
I have testing environment which is perfectly working with chrome driver in desktop mode. I am using some javascript injections (everything works) f.e.:
public static void ForceFillInput(this Driver driver, string selector, string value)
{
var javaScriptExecutor = (IJavaScriptExecutor)driver.webDriver;
javaScriptExecutor.ExecuteScript($"$(\"{selector}\").val(\"{value}\")");
}
but when i want to run it in headless mode
AddArguments("--headless")
it will just fail on
"$ is not defined"
Can somebody help me how to inject js/jquery into headless solution?
M.
your Javascript snippet used jQuery api. In modern web development, we put Javascript at the end of HTML page to let browser to load javascript at last, so that static resources (like picture/image/text content) can display earlier as possible, withing this way to improve user experience when user open website.
I think your page also put jQuery at the end to load, try add some wait/sleep before ExecuteScript to wait browser complete load jQuery.
It looks like the shorthand for JQuery is not yet created at the time your script is executed.
Use a waiter to wait for JQuery and for the selector to be found:
public static void ForceFillInput(this Driver driver, string selector, string value)
{
string JS_SET_VALUE =
"var e; return !!window.$ && (e = window.$(arguments[0])).length > 0 && (e.val(arguments[1]), true);";
new WebDriverWait(driver, TimeSpan.FromSeconds(60))
.until(ctx => (bool)((IJavaScriptExecutor)ctx).ExecuteScript(JS_SET_VALUE, selector, value));
}
I am trying to automate a test on my site using selenium web driver for javascript.
How can I approach running tests here using the wait method with content that may not be ready when the page loads eg data comes from an external api etc?
In my example my content is getting loaded by an external js file. You can see what the page looks like in this fiddle I couldn't link it in my code below as the fiddle gets wrapped in an iframe.
<head>
<script src="https://cdn.auth0.com/js/lock/10.2/lock.min.js"></script>
</head>
<body onload="lock.show();">
<div id="content">
<script type="text/javascript">
var domain = 'contoso.auth0.com';
var clientID = 'DyG9nCwIEofSy66QM3oo5xU6NFs3TmvT';
var lock = new Auth0Lock(clientID, domain);
lock.show({
focusInput: false,
popup: true,
}, function (err, profile, token) {
alert(err);
});
</script>
</div>
</body>
I can get it working using sleep, but can't guarentee my content will be ready after the timeout has finished.
const {Builder, By, Key, until} = require('selenium-webdriver');
let driver = new Builder()
.forBrowser('firefox')
.build();
driver.get('MY_URL')
driver.sleep(2000).then(function() {
driver.findElement(By.name('email')).sendKeys('test#test.com')
driver.findElement(By.name('password')).sendKeys('test')
//driver.findElement(By.className('auth0-lock-submit')).click()
})
But if I try with wait
function login() {
return driver.findElement(By.name('email')).sendKeys('test#test.com')
}
driver.get('MY_URL')
driver.wait(login, 5000)
I get NoSuchElementError: Unable to locate element: *[name="email"]
How can I get this working so that I wait for my content to be available before proceeding.
The implicit wait will tell to the web driver to wait for certain amount of time before it throws a "No Such Element Exception". The default setting is 0. Once we set the time, web driver will wait for that time before throwing an exception..
driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
Try to use FluentWait. Create a by function of your element which you want to wait and pass it in below method
WebElement waitsss(WebDriver driver, By elementIdentifier){
Wait<WebDriver> wait =
new FluentWait<WebDriver>(driver).withTimeout(60, TimeUnit.SECONDS) .pollingEvery(1, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
return wait.until(new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
return driver.findElement(elementIdentifier);
}});
}
Code for Explicit wait:
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[contains(.,'Next')]")));
refer :-
https://www.guru99.com/implicit-explicit-waits-selenium.html
I did a simple demo when useing JxBrowser Calling Java from JavaScript, and then I found the phenomenon,
public static void main(String[] args) {
// TODO Auto-generated method stub
BrowserPreferences.setChromiumSwitches("--remote-debugging-port=9222");
Browser browser1 = new Browser();
BrowserView browserView1 = new BrowserView(browser1);
// Gets URL of the remote Developer Tools web page for browser1 instance.
String remoteDebuggingURL = browser1.getRemoteDebuggingURL();
browser1.addScriptContextListener(new ScriptContextAdapter() {
#Override
public void onScriptContextCreated(ScriptContextEvent event) {
Browser browser = event.getBrowser();
JSValue window = browser.executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("java", new JavaObject());
}
});
JFrame frame1 = new JFrame();
frame1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame1.add(browserView1, BorderLayout.CENTER);
frame1.setSize(700, 500);
frame1.setLocationRelativeTo(null);
frame1.setVisible(true);
browser1.loadURL("https://www.baidu.com");
// Creates another Browser instance and loads the remote Developer
// Tools URL to access HTML inspector.
Browser browser2 = new Browser();
BrowserView browserView2 = new BrowserView(browser2);
JFrame frame2 = new JFrame();
frame2.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame2.add(browserView2, BorderLayout.CENTER);
frame2.setSize(700, 500);
frame2.setLocationRelativeTo(null);
frame2.setVisible(true);
browser2.loadURL(remoteDebuggingURL);
}
I run the code and refresh the chrome, many times and then
before refresh
refresh 2 Minute
if user other network with more resources or images ,The Memory increase more faster, Would like to ask whether this problem can be solved
thanks all!
I'm looking forward to the reply!
I checked your example and I confirm that it is an issue in JxBrowser. I've created the corresponding task in our issue tracking system. We will fix this issue in one of the next JxBrowser versions. I will let you know when the new build with the fix is available for download.
I am looking for a way to confirm the image has actually loaded. Maybe JavaScript is an option? I am using right now WebdriverWait to simply force the wait on all images, then the actual src, then I finally run my tests after...
wait = WebDriverWait(driver, 10)
...
albums = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".albums .album img")))
albumslength = len(albums)-1
while albumslength > 0:
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ('.album:nth-child('+str(albumslength)+') img[src*="album-foo"]'))))
albumslength -= 1
...
This will at some point confirm "album-foo" exists in the <img src="http://www.album-foo/images/blah.jpg" of each album in albums. But it does not confirm that the image completed loading into view. I have searched high and low, anyone have a solution?
I am testing on Chrome and Firefox, so no phantom or IE restrictions, if the ideas grow into including JavaScript or related ideas that might have environment restrictions.
I am not that experienced with selenium, though I will give this a try.
If you want to check whether an image is loaded, I'd say use a boolean. Set the original value of this boolean let's say 'loaded' to false.
Then just call something like this, making sure it returns true the moment the image has loaded.
Boolean loaded = false;
WebDriver driver = new AnyDriverYouWant();
JavascriptExecutor js;
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor)driver;
}
loaded = (Boolean)js.executeScript("image.onload(function() { return true; });");
Background
I have a network performance testing tool which after every test,displays all its results in a new results page. Below is my workflow to find the final value.(Details not relevant here but the html elements i am looking for might
1.Go to a section called "Data frame" ( which has a table with timestamp,transmit,recieve and percentage as columns) and get the time stamp when percentage first drops below 99.9
Here is a snippet of the "Data Frame" table
Data frame snippet
2.Go to another section called "Data throughput" ( table with timestamp, throughput as columns) and get the maximum value of throughput before the previously found timestamp.
After every test, i have to do this manually, but there should be someway to automate this.
Question
1.Is it possible to write a script ( maybe in javascript ) to automate my workflow for every new results page?
example algorithm
section = webpage.section_with_title("Data frames")
for each row in section
find first my_timestamp with percent < 99.9
done
section2 = webpage.section_with_title("Data Throughput")
for each row in section2
find max row.throughput if row.timestamp < my_timestamp
don
2.Once i write the script, how do i execute it in the web page?
3.Can i leverage the firefox/chrome developer console in some way ?
Note:I develop mostly in C,C++ and ruby with very basic experience in HTML and CSS. I have barely used javascript, but i have a vague idea that the browsers use it to handle the content of every page.
My thought process was to somehow execute the script through firefox console, and it will provide me with the results... is that difficult?
edit: since i am not familiar with the web development terms, ill put an a different choice of words...
1.i open up the results page
2.i open the console window of firefox/chrome
3.run my script(dont know what language).
4.i should get the result in the console. i do not want to modify the results page. i just need the result displayed to me(in the console, or to a text file).
Yes it's possible to do what you think using Javascript. Please look up XMLHttpRequest
Here is a way for you to start (in Java):
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class YourClass
{
private WebDriver webDriver = null;
public void open() throws Exception
{
webDriver = new FirefoxDriver();
}
public void close() throws Exception
{
webDriver.quit();
}
public void doStuff() throws Exception
{
WebElement element = webDriver.findElement(By.id(...));
...
// Alternatively, it might be easier to parse the entire
// page-source instead of searching elements in the DOM
String pageSource = webDriver.getPageSource();
...
}
}
You will need to download the following JAR files and add them in your project's class-path:
selenium-java-2.xx.0.jar (currently xx=39)
selenium-server-standalone-2.xx.0.jar (currently xx=39)