Skip to content

Instantly share code, notes, and snippets.

@klepikov
Last active August 25, 2023 03:12
Show Gist options
  • Save klepikov/5457750 to your computer and use it in GitHub Desktop.
Save klepikov/5457750 to your computer and use it in GitHub Desktop.
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");
}
}
@shubhamsharmas
Copy link

shubhamsharmas commented Jan 8, 2022

Can someone help me understand in the WebPageTest what is the baseURL? and the location? because i get the below error while running
Exception in thread "main" org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]
at org.json.JSONTokener.syntaxError(JSONTokener.java:507)
at org.json.JSONObject.(JSONObject.java:225)
at video.ui.automation.stepDefinition.WebPageTest.createTest(WebPageTest.java:57)
at video.ui.automation.stepDefinition.WebPageTest.submitResult(WebPageTest.java:24)

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