Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Demo code for the GTAC 2013 talk "Web Performance Testing with WebDriver" by Michael Klepikov
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import org.json.*;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.*;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.*;
public class Test {
private static final String WEBDRIVER_SERVER_URL = "http://localhost:9515/";
private static String androidPackage = null; // Assigned in main()
private WebDriver driver;
public void testGoogleSearch() throws Exception {
driver.get("http://www.google.com/news");
WebElement element = driver.findElement(By.name("q"));
element.sendKeys("Selenium Conference 2013");
element.submit();
driver.findElement(By.linkText("Web")).click();
}
public void setUp() throws Exception {
DesiredCapabilities caps = DesiredCapabilities.chrome();
if (null != androidPackage) {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOptions("androidPackage", androidPackage);
caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
}
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
logPrefs.enable(LogType.PERFORMANCE, Level.INFO);
caps.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
driver = new Augmenter().augment(new RemoteWebDriver(new URL(WEBDRIVER_SERVER_URL), caps));
Capabilities actualCaps = ((HasCapabilities) driver).getCapabilities();
System.out.println("Actual caps: " + actualCaps);
}
public void tearDown() throws Exception {
try {
Logs logs = driver.manage().logs();
System.out.println("Log types: " + logs.getAvailableLogTypes());
printLog(LogType.BROWSER);
submitPerformanceResult("Test.testGoogleSearch", logs.get(LogType.PERFORMANCE).getAll());
} finally {
driver.quit();
}
}
void printLog(String type) {
List<LogEntry> entries = driver.manage().logs().get(type).getAll();
System.out.println(entries.size() + " " + type + " log entries found");
for (LogEntry entry : entries) {
System.out.println(
new Date(entry.getTimestamp()) + " " + entry.getLevel() + " " + entry.getMessage());
}
}
void submitPerformanceResult(String name, List<LogEntry> perfLogEntries)
throws IOException, JSONException {
JSONArray devToolsLog = new JSONArray();
System.out.println(perfLogEntries.size() + " performance log entries found");
for (LogEntry entry : perfLogEntries) {
JSONObject message = new JSONObject(entry.getMessage());
JSONObject devToolsMessage = message.getJSONObject("message");
// System.out.println(
// devToolsMessage.getString("method") + " " + message.getString("webview"));
devToolsLog.put(devToolsMessage);
}
byte[] screenshot = null;
if (null == androidPackage) { // Chrome on Android does not yet support screenshots
screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
String resultUrl = new WebPageTest(new URL("http://localhost:8888/"), "Test", name)
.submitResult(devToolsLog, screenshot);
System.out.println("Result page: " + resultUrl);
}
public static void main(String[] argv) throws Exception {
if (argv.length > 0 && "--android".equals(argv[0])) {
// androidPackage = "com.google.android.apps.chrome_dev";
androidPackage = "com.google.android.apps.chrome";
}
Test test = new Test();
test.setUp();
try {
test.testGoogleSearch();
} finally {
test.tearDown();
}
}
}
# This does not include WebPageTest submission, only an illustration
# how to use the Logging API from the WebDriver Python bindings.
from selenium import webdriver
from selenium.webdriver.common import keys
driver = webdriver.Chrome(
executable_path="chromedriver2_server",
desired_capabilities={'loggingPrefs': {'profiler': 'INFO'}})
# Hack the Logging API into the Python remote driver.
# Not implemented in Selenium, patch welcome!!
driver.command_executor._commands.update({
'getAvailableLogTypes': ('GET', '/session/$sessionId/log/types'),
'getLog': ('POST', '/session/$sessionId/log')})
try:
print 'Available log types:', driver.execute('getAvailableLogTypes')['value']
driver.get('http://news.google.com')
elem = driver.find_element_by_name('q') # Find the query box
elem.send_keys('GTAC 2013' + keys.Keys.RETURN)
elem = driver.find_element_by_link_text('Web')
elem.click()
print 'Profiler log:', driver.execute('getLog', {'type': 'performance'})['value']
finally:
driver.quit()
import java.io.*;
import java.net.*;
import java.util.zip.*;
import org.json.*;
public class WebPageTest {
private final String location;
private final URL createTestUrl;
private final URL workDoneUrl;
private final String mimeBoundary = "-----CorrectBatteryHorseStaple";
public WebPageTest(URL baseUrl, String location, String testUrl) throws IOException {
this.location = location;
this.createTestUrl = new URL(baseUrl,
"runtest.php?location=" + location + "&url=" + URLEncoder.encode(testUrl, "UTF-8") +
"&fvonly=1&f=json");
this.workDoneUrl = new URL(baseUrl, "work/workdone.php");
}
public String submitResult(JSONArray devToolsLog, byte[] screenshot) throws IOException, JSONException {
JSONObject testDescriptor = createTest();
postResult(testDescriptor, devToolsLog, screenshot);
return testDescriptor.getJSONObject("data").getString("userUrl");
}
private void writeResultsZip(OutputStream os, JSONArray devToolsLog, byte[] screenshot)
throws IOException, JSONException {
ZipOutputStream zos = new ZipOutputStream(os);
if (null != devToolsLog) {
zos.putNextEntry(new ZipEntry("1_devtools.json"));
OutputStreamWriter writer = new OutputStreamWriter(zos);
devToolsLog.write(writer);
writer.flush();
zos.closeEntry();
}
if (null != screenshot) {
zos.putNextEntry(new ZipEntry("1_screen.png"));
zos.write(screenshot);
zos.closeEntry();
}
zos.finish();
}
private JSONObject createTest() throws IOException, JSONException {
HttpURLConnection http = (HttpURLConnection) createTestUrl.openConnection();
if (HttpURLConnection.HTTP_OK != http.getResponseCode()) {
throw new IOException("WebPateTest test creation failed for location " + location + ": " +
http.getResponseCode() + " " +http.getResponseMessage());
}
Reader reader = new InputStreamReader(http.getInputStream(), "UTF-8");
try {
return new JSONObject(new JSONTokener(reader));
} finally {
reader.close();
}
}
private void postResult(JSONObject testDescriptor, JSONArray devToolsLog, byte[] screenshot)
throws IOException, JSONException {
HttpURLConnection http = (HttpURLConnection) workDoneUrl.openConnection();
http.setDoOutput(true);
http.addRequestProperty("Content-Type", "multipart/form-data; boundary=" +
mimeBoundary);
http.setChunkedStreamingMode(4096);
writeMultipartContent(http.getOutputStream(), testDescriptor, devToolsLog, screenshot);
http.getInputStream().close();
if (HttpURLConnection.HTTP_OK != http.getResponseCode()) {
throw new IOException("Result submission failed for " +
testDescriptor.getJSONObject("data").getString("userUrl") + " : " +
http.getResponseCode() + " " +http.getResponseMessage());
}
}
private void writeMultipartContent(
OutputStream os, JSONObject testDescriptor, JSONArray devToolsLog, byte[] screenshot)
throws IOException, JSONException {
String testId = testDescriptor.getJSONObject("data").getString("testId");
OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
startMimePart(writer, "location", null);
writer.write("\r\n" + location + "\r\n");
startMimePart(writer, "id", null);
writer.write("\r\n" + testId + "\r\n");
startMimePart(writer, "done", null);
writer.write("\r\n1\r\n");
startMimePart(writer, "file", "1_results.zip");
writer.write("Content-Type: application/zip\r\n");
writer.write("Content-Transfer-Encoding: binary\r\n\r\n");
writer.flush();
writeResultsZip(os, devToolsLog, screenshot);
writer.write("\r\n--");
writer.write(mimeBoundary);
writer.write("--\r\n");
writer.flush();
}
private void startMimePart(Writer writer, String name, String filename) throws IOException {
writer.write("--");
writer.write(mimeBoundary);
writer.write("\r\n");
writer.write("Content-Disposition: form-data; name=\"");
writer.write(name);
if (null != filename) {
writer.write("\"; filename=\"");
writer.write(filename);
}
writer.write("\"\r\n");
}
}
@neelk

This comment has been minimized.

Show comment
Hide comment
@neelk

neelk Apr 25, 2013

Hi Michael,

Thanks a lot for sharing the code. I was trying to implement the same for our Webdriver test framework but got following error:

Exception in thread "main" java.io.IOException: Result submission failed for http://www.webpagetest.org/result/130425_MX_185S/ : 411 Length Required
at WebPageTest.postResult(WebPageTest.java:75)
at WebPageTest.submitResult(WebPageTest.java:26)
at Test.submitPerformanceResult(Test.java:65)
at Test.tearDown(Test.java:44)
at Test.main(Test.java:79)

We don't have private instance of Webpagetest, so I used the public instance (webpagetest.org) for both running the test (runtest.php) and submitting the test result logs (work/workdone.php). I am not sure where I am making the mistake.

Thanks,
Neel

neelk commented Apr 25, 2013

Hi Michael,

Thanks a lot for sharing the code. I was trying to implement the same for our Webdriver test framework but got following error:

Exception in thread "main" java.io.IOException: Result submission failed for http://www.webpagetest.org/result/130425_MX_185S/ : 411 Length Required
at WebPageTest.postResult(WebPageTest.java:75)
at WebPageTest.submitResult(WebPageTest.java:26)
at Test.submitPerformanceResult(Test.java:65)
at Test.tearDown(Test.java:44)
at Test.main(Test.java:79)

We don't have private instance of Webpagetest, so I used the public instance (webpagetest.org) for both running the test (runtest.php) and submitting the test result logs (work/workdone.php). I am not sure where I am making the mistake.

Thanks,
Neel

@klepikov

This comment has been minimized.

Show comment
Hide comment
@klepikov

klepikov Apr 26, 2013

I believe this is somewhere between apache/ngnx and PHP -- they don't want to accept a POST with "Transfer-Encoding: chunked". So 1st, go to your webpagetest-base-URL/install -- a self-diagnostics page, and make sure everything is reasonably green and recent. Make sure you are running a recent version of Apache and PHP. I am running WPT under MAMP on OSX 10.8.3 (my laptop), with Apache 2.2.21 and PHP 5.3.6. Also sync WebPageTest itself to head, because only the head as of about a week ago has good support for DevTools trace processing.

If you can't get it to work by just upgrading, then change the upload to specify the Content-Length header. Dump the multipart into a new ByteArrayOutputStream instead of http.getOutputStream(), replace the call http.setChunkedStreamingMode(...) with http.setFixedLengthStreamingMode(byteArrayStream.size()) -- this will set "Content-Length: ...", and then use byteArrayStream.writeTo(http.getOutputStream()).

Ah, you are using the actual www.webpagetest.org... Do you have an API key? I am also not sure if it's synced closed enough to head yet to understand a DevTools upload -- that instance is usually a bit more conservative, stays on the more stable side. I suggest to run your own local instance -- it's not hard at all if you already have apache/ngnx + PHP, basically you just point the web content directory under the synced source/www/webpagetest and tweak a few lines in settings/settings.ini and settings/locations.ini, and then you have free reign of the whole thing.

Owner

klepikov commented Apr 26, 2013

I believe this is somewhere between apache/ngnx and PHP -- they don't want to accept a POST with "Transfer-Encoding: chunked". So 1st, go to your webpagetest-base-URL/install -- a self-diagnostics page, and make sure everything is reasonably green and recent. Make sure you are running a recent version of Apache and PHP. I am running WPT under MAMP on OSX 10.8.3 (my laptop), with Apache 2.2.21 and PHP 5.3.6. Also sync WebPageTest itself to head, because only the head as of about a week ago has good support for DevTools trace processing.

If you can't get it to work by just upgrading, then change the upload to specify the Content-Length header. Dump the multipart into a new ByteArrayOutputStream instead of http.getOutputStream(), replace the call http.setChunkedStreamingMode(...) with http.setFixedLengthStreamingMode(byteArrayStream.size()) -- this will set "Content-Length: ...", and then use byteArrayStream.writeTo(http.getOutputStream()).

Ah, you are using the actual www.webpagetest.org... Do you have an API key? I am also not sure if it's synced closed enough to head yet to understand a DevTools upload -- that instance is usually a bit more conservative, stays on the more stable side. I suggest to run your own local instance -- it's not hard at all if you already have apache/ngnx + PHP, basically you just point the web content directory under the synced source/www/webpagetest and tweak a few lines in settings/settings.ini and settings/locations.ini, and then you have free reign of the whole thing.

@neelk

This comment has been minimized.

Show comment
Hide comment
@neelk

neelk Apr 26, 2013

Thank you for your quick response. I do have the API key for www.webpagetest.org. I am able to create the test URL with public instance of webpagetest. I am facing problem with uploading the test result to webpagetest.org with workdone.php.

As you suggested, I'll try to setup the local instance of webpagetest and then try to upload the test result.

neelk commented Apr 26, 2013

Thank you for your quick response. I do have the API key for www.webpagetest.org. I am able to create the test URL with public instance of webpagetest. I am facing problem with uploading the test result to webpagetest.org with workdone.php.

As you suggested, I'll try to setup the local instance of webpagetest and then try to upload the test result.

@klepikov

This comment has been minimized.

Show comment
Hide comment
@klepikov

klepikov Apr 30, 2013

The other reason you would want a local instance even after you get past the chunked encoding issue, is you won't be able to post a result to any of the public webpagetest.org locations -- it only allows its test agents to do that:) In a private instance you just configure a location with no restrictions and post to it.

BTW I just realized -- revision 1 of this gist has WebPageTest.java that does a POST with Content-Length:) I did that for debugging, it also dumps out a file with the POST content.

Owner

klepikov commented Apr 30, 2013

The other reason you would want a local instance even after you get past the chunked encoding issue, is you won't be able to post a result to any of the public webpagetest.org locations -- it only allows its test agents to do that:) In a private instance you just configure a location with no restrictions and post to it.

BTW I just realized -- revision 1 of this gist has WebPageTest.java that does a POST with Content-Length:) I did that for debugging, it also dumps out a file with the POST content.

@praveen2288

This comment has been minimized.

Show comment
Hide comment
@praveen2288

praveen2288 May 25, 2013

Hi Michael,

Thanks for the code. I closely follow your seleniumconf and Google Tech Talk presentations. Your blog on setting up private instance was very useful.

Now that I tried to run this code. Everytime I get this error.

2223 performance log entries found
Exception in thread "main" org.json.JSONException: JSONObject["data"] not found.
at org.json.JSONObject.get(JSONObject.java:454)

Can you help me in this?

Praveen.

praveen2288 commented May 25, 2013

Hi Michael,

Thanks for the code. I closely follow your seleniumconf and Google Tech Talk presentations. Your blog on setting up private instance was very useful.

Now that I tried to run this code. Everytime I get this error.

2223 performance log entries found
Exception in thread "main" org.json.JSONException: JSONObject["data"] not found.
at org.json.JSONObject.get(JSONObject.java:454)

Can you help me in this?

Praveen.

@praveen2288

This comment has been minimized.

Show comment
Hide comment
@praveen2288

praveen2288 May 28, 2013

Hi Michael,

I resolved the above mentioned issue. It works like charm. Problem was with Location attribute in URL while creating the test. It was not able to find the location 'Test' in my private instance.

Praveen.

praveen2288 commented May 28, 2013

Hi Michael,

I resolved the above mentioned issue. It works like charm. Problem was with Location attribute in URL while creating the test. It was not able to find the location 'Test' in my private instance.

Praveen.

@sbarda

This comment has been minimized.

Show comment
Hide comment
@sbarda

sbarda Jun 19, 2013

Hi Michael,

I posted a comment here yesterday but don't see it here now. So I'm re-posting.

I use Selenium WebDriver and write tests using Java code. I'd like to try out your test code, but I need more direction to make your example code work. Can you please write up a step-by-step tutorial on how to make your tests work? I'm anxious to try this out.

Thanks!
Seth

sbarda commented Jun 19, 2013

Hi Michael,

I posted a comment here yesterday but don't see it here now. So I'm re-posting.

I use Selenium WebDriver and write tests using Java code. I'd like to try out your test code, but I need more direction to make your example code work. Can you please write up a step-by-step tutorial on how to make your tests work? I'm anxious to try this out.

Thanks!
Seth

@arex1337

This comment has been minimized.

Show comment
Hide comment
@arex1337

arex1337 Jun 19, 2013

Hi,

Is this possible to replicate with C# bindings?

For starters, I can't find the equivalent of LoggingPreferences or driver.manage().logs().

arex1337 commented Jun 19, 2013

Hi,

Is this possible to replicate with C# bindings?

For starters, I can't find the equivalent of LoggingPreferences or driver.manage().logs().

@mugilela

This comment has been minimized.

Show comment
Hide comment
@mugilela

mugilela Jun 25, 2013

HI,
I tried your demo code, but get the exception :
java.net.ConnectException: Connection refused

Could you please let me know if am missing anything.
THanks
Mugil

mugilela commented Jun 25, 2013

HI,
I tried your demo code, but get the exception :
java.net.ConnectException: Connection refused

Could you please let me know if am missing anything.
THanks
Mugil

@ryanarioli

This comment has been minimized.

Show comment
Hide comment
@ryanarioli

ryanarioli Oct 16, 2013

Hi Michael,

I was wondering about the Python code example you have above. When I run the example code to check the performance logs, it says that type does not exist? Do the performance logs need to be enabled in the webdriver? Just thought I'd get your two cents.

Thanks,

Ryan

ryanarioli commented Oct 16, 2013

Hi Michael,

I was wondering about the Python code example you have above. When I run the example code to check the performance logs, it says that type does not exist? Do the performance logs need to be enabled in the webdriver? Just thought I'd get your two cents.

Thanks,

Ryan

@anselmo

This comment has been minimized.

Show comment
Hide comment
@anselmo

anselmo Jan 2, 2014

@ryanarioli on line 9, try 'performance' instead of 'profiler'

desired_capabilities={'loggingPrefs': {'performance': 'INFO'}})

anselmo commented Jan 2, 2014

@ryanarioli on line 9, try 'performance' instead of 'profiler'

desired_capabilities={'loggingPrefs': {'performance': 'INFO'}})
@b1alpha

This comment has been minimized.

Show comment
Hide comment
@b1alpha

b1alpha Jan 24, 2014

I watched your talk and was just wondering about the webpagetest.org part, I see you have implemented this to work giving results from that service, I would love to integrate these into our teamcity CI and not use werbpagetest. Instead just report through teamcity, what sort of CI have you been using and why did you choose to do it this way? Was it just so you could present data nicely? Thanks!

b1alpha commented Jan 24, 2014

I watched your talk and was just wondering about the webpagetest.org part, I see you have implemented this to work giving results from that service, I would love to integrate these into our teamcity CI and not use werbpagetest. Instead just report through teamcity, what sort of CI have you been using and why did you choose to do it this way? Was it just so you could present data nicely? Thanks!

@DKroot

This comment has been minimized.

Show comment
Hide comment
@DKroot

DKroot Mar 7, 2014

Thanks a lot for posting the code! This looks very promising for our needs of capturing performance baseline in feature tests.

I'm trying to make it work with a private instance of WebPagetest 2.13. I've setup the instance on a built-in Apache HTTP Server in OS X Mavericks and copied locations.ini.sample to locations.ini. The server renders the home page at http://localhost/index.php and I can see "WebPagetest.org - Dulles, VA" location.

When I try to submit performance logs to the server I'm getting:

org.json.JSONException: JSONObject["data"] not found.
    at org.json.JSONObject.get(JSONObject.java:499)
    at org.json.JSONObject.getJSONObject(JSONObject.java:593)
    at com.nete.cukejvmrefapp.WebPageTest.writeMultipartContent(WebPageTest.java:96)
    at com.nete.cukejvmrefapp.WebPageTest.postResult(WebPageTest.java:85)
    at com.nete.cukejvmrefapp.WebPageTest.submitResult(WebPageTest.java:43)
[skipped]

I'll try to troubleshoot, but do you have any ideas about the cause in the meantime?

Just a side note, on a Mac, I had to add Options FollowSymLinks in Apache config under <Directory "/[skipped]/webpagetest"> because I was getting the following error in Apache logs on all URLs under webpagetest/:
[error] [client ::1] Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

DKroot commented Mar 7, 2014

Thanks a lot for posting the code! This looks very promising for our needs of capturing performance baseline in feature tests.

I'm trying to make it work with a private instance of WebPagetest 2.13. I've setup the instance on a built-in Apache HTTP Server in OS X Mavericks and copied locations.ini.sample to locations.ini. The server renders the home page at http://localhost/index.php and I can see "WebPagetest.org - Dulles, VA" location.

When I try to submit performance logs to the server I'm getting:

org.json.JSONException: JSONObject["data"] not found.
    at org.json.JSONObject.get(JSONObject.java:499)
    at org.json.JSONObject.getJSONObject(JSONObject.java:593)
    at com.nete.cukejvmrefapp.WebPageTest.writeMultipartContent(WebPageTest.java:96)
    at com.nete.cukejvmrefapp.WebPageTest.postResult(WebPageTest.java:85)
    at com.nete.cukejvmrefapp.WebPageTest.submitResult(WebPageTest.java:43)
[skipped]

I'll try to troubleshoot, but do you have any ideas about the cause in the meantime?

Just a side note, on a Mac, I had to add Options FollowSymLinks in Apache config under <Directory "/[skipped]/webpagetest"> because I was getting the following error in Apache logs on all URLs under webpagetest/:
[error] [client ::1] Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

@DKroot

This comment has been minimized.

Show comment
Hide comment
@DKroot

DKroot Mar 7, 2014

OK, I debugged the problem. The exception in this case is misleading and is happening because WebPageTest doesn't detect the case where server connection is OK, but test creation returns failure in JSON. I have a patch: replace line #53 (return new JSONObject(new JSONTokener(reader));) with the following:

JSONObject result = new JSONObject(new JSONTokener(reader));
if (!result.has("data")) {
    throw new IOException("WebPageTest test creation failed for location " + location + ": " + result);
}
return result;

Now you get much nicer error messages. For example:

java.io.IOException: WebPageTest test creation failed for location Test: {"statusCode":400,"statusTe
xt":"Error submitting url for testing"}

But there is still a problem, which puzzles me. "Test" location is recognized (otherwise the error message is telling about an invalid location), but is there something wrong with it? What am I missing?

DKroot commented Mar 7, 2014

OK, I debugged the problem. The exception in this case is misleading and is happening because WebPageTest doesn't detect the case where server connection is OK, but test creation returns failure in JSON. I have a patch: replace line #53 (return new JSONObject(new JSONTokener(reader));) with the following:

JSONObject result = new JSONObject(new JSONTokener(reader));
if (!result.has("data")) {
    throw new IOException("WebPageTest test creation failed for location " + location + ": " + result);
}
return result;

Now you get much nicer error messages. For example:

java.io.IOException: WebPageTest test creation failed for location Test: {"statusCode":400,"statusTe
xt":"Error submitting url for testing"}

But there is still a problem, which puzzles me. "Test" location is recognized (otherwise the error message is telling about an invalid location), but is there something wrong with it? What am I missing?

@DKroot

This comment has been minimized.

Show comment
Hide comment
@DKroot

DKroot Mar 10, 2014

On a side note, does anybody have experience in presenting this performance data in any tool other than WebpageTest? The talk mentioned other tools, but no specific examples were provided.

DKroot commented Mar 10, 2014

On a side note, does anybody have experience in presenting this performance data in any tool other than WebpageTest? The talk mentioned other tools, but no specific examples were provided.

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Mar 26, 2014

Web page test gives you an option to export the tool as a har (HTTP Archive) file . You can then use http://www.softwareishard.com/har/viewer/ to view the har file

ghost commented Mar 26, 2014

Web page test gives you an option to export the tool as a har (HTTP Archive) file . You can then use http://www.softwareishard.com/har/viewer/ to view the har file

@pestis

This comment has been minimized.

Show comment
Hide comment
@pestis

pestis Jun 3, 2014

Update 6/3/2014 (Issue Fixed): Issue appears to have resolved itself after moving to a more recent version of the WPT www. Now after submitting multiple test run results to WPT server, the results page is updated immediately and no longer waiting for tests to complete.

We got the code working on our private instance. Thanks a bunch Michael. One issue we are hitting is the following:

After submitting a result and viewing the result page e.g. http:///results.php?test=140603_66_G , it always shows the following until a timeout is hit after 5+ minutes,

Test is partially complete (1 of 1 tests).
This page will refresh as tests complete.

After the timeout is reached and the page refreshes we are able to see the summarized results with the table showing Load Time, First Byte etc. for the median run at the top of the page. My question, is there a way to notify the server that we are done submitting results and to go ahead completing the test run and compile the summary results?

Looking at the current code for workdone.php it looks like the following snippet might be what needs to be done but I’m not 100% sure. If anyone could offer any guidance it would be much appreciated

  // do any post-processing when the full test is complete that doesn't rely on testinfo
    if ($done) {
      logTestMsg($id, "Test Complete");

      // send an async request to the post-processing code so we don't block
      SendAsyncRequest("/work/postprocess.php?test=$id");
    }

pestis commented Jun 3, 2014

Update 6/3/2014 (Issue Fixed): Issue appears to have resolved itself after moving to a more recent version of the WPT www. Now after submitting multiple test run results to WPT server, the results page is updated immediately and no longer waiting for tests to complete.

We got the code working on our private instance. Thanks a bunch Michael. One issue we are hitting is the following:

After submitting a result and viewing the result page e.g. http:///results.php?test=140603_66_G , it always shows the following until a timeout is hit after 5+ minutes,

Test is partially complete (1 of 1 tests).
This page will refresh as tests complete.

After the timeout is reached and the page refreshes we are able to see the summarized results with the table showing Load Time, First Byte etc. for the median run at the top of the page. My question, is there a way to notify the server that we are done submitting results and to go ahead completing the test run and compile the summary results?

Looking at the current code for workdone.php it looks like the following snippet might be what needs to be done but I’m not 100% sure. If anyone could offer any guidance it would be much appreciated

  // do any post-processing when the full test is complete that doesn't rely on testinfo
    if ($done) {
      logTestMsg($id, "Test Complete");

      // send an async request to the post-processing code so we don't block
      SendAsyncRequest("/work/postprocess.php?test=$id");
    }
@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Jun 6, 2014

How to convert the logs to HAR format? Is there any API java? I know that exists in php on the site WebPageTest, but i would like in java.
Thanks!

ghost commented Jun 6, 2014

How to convert the logs to HAR format? Is there any API java? I know that exists in php on the site WebPageTest, but i would like in java.
Thanks!

@tibraga

This comment has been minimized.

Show comment
Hide comment
@tibraga

tibraga Jun 13, 2014

Is there any code in java that converts this log to HAR format?

tibraga commented Jun 13, 2014

Is there any code in java that converts this log to HAR format?

@NickTulett

This comment has been minimized.

Show comment
Hide comment
@NickTulett

NickTulett Jun 18, 2014

How do these Network.responseReceived timing values relate to the timings you would see in Chrome Developer Tools or a WPT waterfall. e.g. TTFB, total request time, etc?

"timing":{
"connectEnd":10.477000032551587,"connectStart":9.941000025719404,
"dnsEnd":9.941000025719404,"dnsStart":9.901000070385635,
"proxyEnd":-1,"proxyStart":-1,
"receiveHeadersEnd":20.198000012896955,
"requestTime":1403001765.7676198,
"sendEnd":11.696000001393259,"sendStart":11.64400007110089,
"sslEnd":-1,"sslStart":-1
}

Do I need to calculate them based on the original Timeline.eventRecorded or Network.requestWillBeSent events for the matching GET request?

NickTulett commented Jun 18, 2014

How do these Network.responseReceived timing values relate to the timings you would see in Chrome Developer Tools or a WPT waterfall. e.g. TTFB, total request time, etc?

"timing":{
"connectEnd":10.477000032551587,"connectStart":9.941000025719404,
"dnsEnd":9.941000025719404,"dnsStart":9.901000070385635,
"proxyEnd":-1,"proxyStart":-1,
"receiveHeadersEnd":20.198000012896955,
"requestTime":1403001765.7676198,
"sendEnd":11.696000001393259,"sendStart":11.64400007110089,
"sslEnd":-1,"sslStart":-1
}

Do I need to calculate them based on the original Timeline.eventRecorded or Network.requestWillBeSent events for the matching GET request?

@Anky1987

This comment has been minimized.

Show comment
Hide comment
@Anky1987

Anky1987 Jul 30, 2014

I am using the code in Test.java but when running this code, i am getting an exception:
org.openqa.selenium.WebDriverException: unknown error: log type 'performance' not found

Anky1987 commented Jul 30, 2014

I am using the code in Test.java but when running this code, i am getting an exception:
org.openqa.selenium.WebDriverException: unknown error: log type 'performance' not found

@PuneeshMotwani

This comment has been minimized.

Show comment
Hide comment
@PuneeshMotwani

PuneeshMotwani Aug 20, 2014

Hi Anky1987,

Did you find any solution. I too am getting the same error?
Thanks
Puneesh

PuneeshMotwani commented Aug 20, 2014

Hi Anky1987,

Did you find any solution. I too am getting the same error?
Thanks
Puneesh

@dashah

This comment has been minimized.

Show comment
Hide comment
@dashah

dashah Aug 29, 2014

@klepikov is it possible to add the capability to an existing webdriver in the middle of a test? I'm trying to figure out how to log a specific page load, and not the whole workflow. (eg. we have to login to access our app, and i don't want to time the login, and landing page load).

dashah commented Aug 29, 2014

@klepikov is it possible to add the capability to an existing webdriver in the middle of a test? I'm trying to figure out how to log a specific page load, and not the whole workflow. (eg. we have to login to access our app, and i don't want to time the login, and landing page load).

@pmeenan

This comment has been minimized.

Show comment
Hide comment
@pmeenan

pmeenan Oct 23, 2014

The upload to a WebPagetest instance is somewhat easier now. You can do a post to /import.php and it will return a test ID. There is also a UI on /import.php for testing it out (post fields are the same as the form fields in the UI).

pmeenan commented Oct 23, 2014

The upload to a WebPagetest instance is somewhat easier now. You can do a post to /import.php and it will return a test ID. There is also a UI on /import.php for testing it out (post fields are the same as the form fields in the UI).

@mediga

This comment has been minimized.

Show comment
Hide comment
@mediga

mediga Jun 12, 2015

Issue "org.openqa.selenium.WebDriverException: unknown error: log type 'performance' not found" has been fixed refer this thread

https://code.google.com/p/selenium/issues/detail?id=8457#c10

mediga commented Jun 12, 2015

Issue "org.openqa.selenium.WebDriverException: unknown error: log type 'performance' not found" has been fixed refer this thread

https://code.google.com/p/selenium/issues/detail?id=8457#c10

@durgartanu

This comment has been minimized.

Show comment
Hide comment
@durgartanu

durgartanu Jun 14, 2016

Thanks for the post.. very valuable. I am getting one issue with the above code.
"unknown error: unhandled inspector error: {"code":-32601,"message":"'Timeline.start' wasn't found"}".
Any idea? thanks in advance.

durgartanu commented Jun 14, 2016

Thanks for the post.. very valuable. I am getting one issue with the above code.
"unknown error: unhandled inspector error: {"code":-32601,"message":"'Timeline.start' wasn't found"}".
Any idea? thanks in advance.

@mvoitko

This comment has been minimized.

Show comment
Hide comment
@mvoitko

mvoitko Nov 14, 2016

@klepikov Could you please be so kind and provide demo example of submitting performance logs to WebPageTest in Python?

mvoitko commented Nov 14, 2016

@klepikov Could you please be so kind and provide demo example of submitting performance logs to WebPageTest in Python?

@galina62

This comment has been minimized.

Show comment
Hide comment
@galina62

galina62 Jan 2, 2017

@klepikov: I run your code. Performance record type appears to only include network activity. I am more interested in client CPU activity. I tried to change code by adding adding/enabling timeline but still got only Network activity records.
Could you please suggest how to retrieve client CPU activity.

Map<String, Object> perfLogPrefs = new HashMap<String, Object>();
perfLogPrefs.put("traceCategories", "browser,devtools.timeline,devtools"); // comma-separated trace categories
perfLogPrefs.put("enableTimeline", true);

galina62 commented Jan 2, 2017

@klepikov: I run your code. Performance record type appears to only include network activity. I am more interested in client CPU activity. I tried to change code by adding adding/enabling timeline but still got only Network activity records.
Could you please suggest how to retrieve client CPU activity.

Map<String, Object> perfLogPrefs = new HashMap<String, Object>();
perfLogPrefs.put("traceCategories", "browser,devtools.timeline,devtools"); // comma-separated trace categories
perfLogPrefs.put("enableTimeline", true);

@Napster158

This comment has been minimized.

Show comment
Hide comment
@Napster158

Napster158 Jul 5, 2017

@klepikov: Could you please be so kind and provide demo example of submitting performance logs to WebPageTest in Python?

Napster158 commented Jul 5, 2017

@klepikov: Could you please be so kind and provide demo example of submitting performance logs to WebPageTest in Python?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment