blob: b460d5b37e494740a10b210bf15be9a3fac7ca8f [file] [log] [blame]
from pltresults import PLTResults
from selenium import webdriver
from time import sleep
from webkitpy.benchmark_runner.utils import get_driver_binary_path
# FIXME: we want to avoid hardcoding the offsets
# we use this to make sure the window.innerHeight of each browser is the same
browser_height_offsets = {
'safari': 76,
'chrome': 0,
'firefox': 37,
'stp': 76,
}
class PageLoadTest(object):
def __init__(self, iterations, instances, wait, browser, suites, size):
print("Creating PLT with parameters:")
print("iterations: {}".format(iterations))
print("instances: {}".format(instances))
print("wait: {}s".format(wait))
print("browser: {}".format(browser))
print("suites: {}".format([s.name for s in suites]))
width, height = size
if width:
print("width: {}".format(width))
if height:
print("height: {}".format(height))
print("")
self.iterations = iterations
self.instances = instances
self.wait = wait
self.browser = browser
self.suites = suites
self.size = size
def start(self):
total_results = PLTResults()
suiteid = 0
for suite in self.suites:
suite.attempts -= 1
suiteid += 1
print("------------------------------")
print("Running suite {id} of {num}: {name}".format(id=suiteid, num=len(self.suites), name=suite.name))
print("------------------------------")
print("")
total_results += self.run_suite(suite)
total_results.print_results()
def run_suite(self, suite):
cold_run_results = PLTResults()
suite_results = PLTResults()
for instance in range(self.instances):
driver = self._get_driver_for_browser(self.browser)
self._setup_browser_window(driver)
sleep(5)
for iteration in range(self.iterations + 1):
print("------------------------------")
if iteration == 0:
print("Running iternation %s (cold run)" % iteration)
else:
print("Running iternation %s" % iteration)
run_results = self.run_one_test(suite, driver)
if not run_results:
if suite.attempts <= 0:
print("Failed to finish suite {name} after {x} attempts. Results are incomplete.".format(name=suite.name, x=suite.max_attempts))
print("Exiting...")
quit()
else:
print("A page failed to load. Re-queuing suite.")
self.suites.append(suite)
driver.quit()
return PLTResults()
run_results.print_url_results("INDIVIDUAL")
if iteration == 0:
cold_run_results += run_results
else:
suite_results += run_results
driver.quit()
cold_run_results.print_results(suite.name, True)
suite_results.print_results(suite.name)
return suite_results
def _get_driver_for_browser(self, browser):
driver_executable = get_driver_binary_path(browser)
if browser == 'safari':
return webdriver.Safari()
if browser == 'chrome':
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--disable-web-security")
options.add_argument("--disable-extensions")
options.add_argument("--start-maximized")
return webdriver.Chrome(chrome_options=options, executable_path=driver_executable)
if browser == 'firefox':
return webdriver.Firefox(executable_path=driver_executable)
if browser == 'stp':
return webdriver.Safari(executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver')
def _setup_browser_window(self, driver):
driver.maximize_window()
sleep(1)
current_size = driver.get_window_size()
new_width, new_height = self.size
if not new_width:
new_width = driver.execute_script('return screen.width;')
print("setting width to {}".format(new_width))
if not new_height:
new_height = current_size['height'] - browser_height_offsets[self.browser]
print("setting height to {}".format(new_height))
try:
driver.set_window_size(width=new_width, height=new_height)
driver.set_window_position(x=0, y=0)
except:
pass
def run_one_test(self, suite, driver):
tabs = False
currentTabIdx = 0
maxTabs = 5
maxRetrys = 5
timeout = 30
local_results = PLTResults()
for url in suite.urls:
if tabs:
if currentTabIdx < maxTabs - 1:
raise NotImplementedError("Opening new tabs is not supported yet.")
driver.switch_to_window(driver.window_handles[currentTabIdx % maxTabs])
currentTabIdx += 1
tempWait = self.wait
for attempt in range(maxRetrys):
driver.set_page_load_timeout(timeout)
try:
driver.get(url)
except:
print("{url} timed out after {time} seconds.".format(url=url, time=timeout))
return None
sleep(tempWait)
if self.get_results(driver, local_results, url):
break
print("Could not get results for {url}. Retrying...".format(url=url))
tempWait += 0.5
if attempt == maxRetrys - 1:
return None
return local_results
def get_results(self, driver, results, url):
nt_results = driver.execute_script('return performance.getEntriesByType("navigation")[0]') # navigation timing 2
if not nt_results:
nt_results = driver.execute_script('return performance.timing') # navigation timing 1
start = nt_results['navigationStart']
end = nt_results['loadEventEnd']
if start == 0 or end == 0:
return False
else:
start = nt_results['startTime']
end = nt_results['loadEventEnd']
if end == 0:
return False
results.add_timing_result(end - start, url)
return True