Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

479 lines (374 sloc) 16.177 kb
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Crash Tests Selenium Tests.
#
# The Initial Developer of the Original Code is
# Mozilla.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Burns
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
from selenium import selenium
import re
import time
import base64
from page import Page
class CrashStatsBasePage(Page):
_page_heading = 'css=div.page-heading > h2'
def __init__(self, testsetup):
Page.__init__(self, testsetup)
self.sel = self.selenium
@property
def page_title(self):
return self.sel.get_title()
@property
def page_heading(self):
self.wait_for_element_present(self._page_heading)
return self.sel.get_text(self._page_heading)
def get_attribute(self, element, attribute):
return self.sel.get_attribute(element + '@' + attribute)
def get_url_path(self, path):
self.sel.open(path)
def select_product(self, application):
'''
Select the Mozilla Product you want to report on
'''
self.sel.select(self._product_select, application)
self.sel.wait_for_page_to_load(self.timeout)
def select_version(self, version):
'''
Select the version of the application you want to report on
'''
self.sel.select(self._product_version_select, version)
self.sel.wait_for_page_to_load(self.timeout)
def select_report(self, report_name):
'''
Select the report type from the drop down
and wait for the page to reload
'''
self.sel.select(self._report_select, report_name)
self.sel.wait_for_page_to_load(self.timeout)
if 'Top Crashers' == report_name:
return CrashStatsTopCrashers(self.testsetup)
elif 'Top Crashers by Domain' == report_name:
return CrashStatsTopCrashersByDomain(self.testsetup)
elif 'Top Crashers by URL' == report_name:
return CrashStatsTopCrashersByUrl(self.testsetup)
elif 'Top Crashers by TopSite' == report_name:
return CrashStatsTopCrashersBySite(self.testsetup)
elif 'Crashes per User' == report_name:
return CrashStatsPerActiveDailyUser(self.testsetup)
def click_server_status(self):
self.sel.click('link=Server Status')
self.sel.wait_for_page_to_load(self.timeout)
return CrashStatsStatus(self.testsetup)
def click_advanced_search(self):
self.sel.click('link=Advanced Search')
return CrashStatsAdvancedSearch(self.testsetup)
def can_find_text(self, text_to_search):
'''
finds if text is available on a page.
'''
return self.sel.is_text_present(text_to_search)
def wait_for_element_present(self, element):
count = 0
while not self.sel.is_element_present(element):
time.sleep(1)
count += 1
if count == 20:
self.record_error()
raise Exception(element + ' has not loaded')
def wait_for_element_visible(self, element):
self.wait_for_element_present(element)
count = 0
while not self.sel.is_visible(element):
time.sleep(1)
count += 1
if count == 20:
self.record_error()
raise Exception(element + " is still visible")
@property
def current_details(self):
details = {}
details['product'] = self.sel.get_selected_value(self._product_select)
try:
details['versions'] = self.sel.get_text(
'xpath=//select[@id="product_version_select"]/optgroup[2]').split(' ')
except:
details['versions'] = []
return details
def record_error(self):
'''
'''
print '-------------------'
print 'Error at ' + self.sel.get_location()
print 'Page title ' + self.sel.get_title()
print '-------------------'
filename = 'socorro_' + str(time.time()).split('.')[0] + '.png'
print 'Screenshot of error in file ' + filename
f = open(filename, 'wb')
f.write(base64.decodestring(
self.sel.capture_entire_page_screenshot_to_string('')))
f.close()
class CrashStatsHomePage(CrashStatsBasePage):
'''
Page Object for Socorro
'''
_find_crash_id_or_signature = 'id=q'
_product_select = 'id=products_select'
_product_version_select = 'id=product_version_select'
_report_select = 'id=report_select'
_first_product_top_crashers_link_locator = 'css=#release_channels .release_channel:first li:first a'
_first_signature_locator = 'css=div.crash > p > a'
_second_signature_locator = 'css=.crash:nth(2) > p > a'
_top_crashers = 'css=a:contains("Top Crashers")'
_top_changers = 'css=a:contains("Top Changers")'
_top_crashers_selected = _top_crashers + '.selected'
_top_changers_selected = _top_changers + '.selected'
def __init__(self, testsetup):
'''
Creates a new instance of the class and gets the page ready for testing
'''
CrashStatsBasePage.__init__(self, testsetup)
self.sel.open('/')
count = 0
while not re.search(r'http?\w://.*/products/.*', self.sel.get_location(), re.U):
time.sleep(1)
count += 1
if count == 20:
self.record_error()
raise Exception("Home Page has not loaded")
if not self.sel.get_title() == 'Crash Data for Firefox':
self.sel.select(self.product_select, 'Firefox')
self.sel.wait_for_page_to_load(self.timeout)
self.sel.window_maximize()
def report_length(self, days):
'''
Click on the link with the amount of days you want the report to be
'''
self.sel.click('link=' + days + ' days')
self.sel.wait_for_page_to_load(self.timeout)
self.wait_for_element_present('xpath=//a[text()="'
+ days + ' days" and @class="selected"]')
def search_for_crash(self, crash_id_or_signature):
'''
Type the signature or the id of a bug into the search bar and submit the form
'''
self.sel.type(self._find_crash_id_or_signature, crash_id_or_signature)
self.sel.key_press(self._find_crash_id_or_signature, "\\13")
#self.sel.submit('//form')
self.sel.wait_for_page_to_load(self.timeout)
return CrashStatsSearchResults(self.testsetup)
def click_on_top_(self, element):
topElement = 'link=Top ' + element
self.sel.click(topElement)
if element == 'Changers':
self.wait_for_element_visible(self._top_changers_selected)
else:
self.wait_for_element_visible(self._top_crashers_selected)
def click_first_product_top_crashers_link(self):
self.sel.click(self._first_product_top_crashers_link_locator)
self.sel.wait_for_page_to_load(self.timeout)
return CrashReportList(self.testsetup)
@property
def product_list(self):
return self.sel.get_select_options(self._product_select)
@property
def first_signature(self):
return self.sel.get_text(self._first_signature_locator)
class CrashReportList(CrashStatsBasePage):
_reports_list_locator = 'css=#signatureList tbody tr'
_signature_locator = _reports_list_locator + ":nth-of-type(%s) td:nth-of-type(5) a"
_signature_text_locator = _signature_locator + " span"
def get_report(self, index):
return CrashReport(self.testsetup, index)
def set_report(self, index):
signature = self.get_signature(index)
return CrashReport(self.testsetup, index, signature)
def get_signature(self, index):
return self.sel.get_text(self._signature_text_locator % index)
def click_signature(self, index):
report = self.reports[index]
self.sel.click(self._signature_locator % index)
self.sel.wait_for_page_to_load(self.timeout)
return report
def click_first_valid_signature(self):
return self.click_signature(self.first_report_with_valid_signature.row_index)
@property
def first_valid_signature(self):
return self.get_signature(self.first_report_with_valid_signature.row_index)
@property
def reports(self):
return [self.get_report(count) for count in range(1, self.reports_count)]
@property
def reports_count(self):
return self.sel.get_css_count(self._reports_list_locator)
@property
def first_report_with_valid_signature(self):
return [report for report in self.reports if report.has_valid_signature][0]
class CrashReport(CrashStatsBasePage):
_product_locator = " td:nth-of-type(3)"
_version_locator = " td:nth-of-type(4)"
_row_locator = "css=#reportsList tbody tr"
def __init__(self, testsetup, index, signature=None):
CrashStatsBasePage.__init__(self, testsetup)
self.index = index
self._signature = signature
def absolute_locator(self, relative_locator):
return self.root_locator + relative_locator
@property
def root_locator(self):
return self._row_locator + ":nth-of-type(%s)" % (self.index)
@property
def row_index(self):
return self.index
@property
def row_count(self):
return self.sel.get_css_count(self._row_locator)
@property
def signature(self):
return self._signature
@property
def product(self):
return self.sel.get_text(self.absolute_locator(self._product_locator))
@property
def version(self):
return self.sel.get_text(self.absolute_locator(self._version_locator))
@property
def has_valid_signature(self):
if self.signature == "(empty signature)":
return False
return True
class CrashStatsAdvancedSearch(CrashStatsBasePage):
_product_multiple_select = 'id=product'
_filter_crash_reports_button = 'id=query_submit'
_data_table = 'id=signatureList'
_data_table_first_signature = 'css=table#signatureList > tbody > tr > td > a'
def __init__(self, testsetup):
'''
Creates a new instance of the class and gets the page ready for testing
'''
CrashStatsBasePage.__init__(self, testsetup)
count = 0
self.wait_for_element_present(self._product_multiple_select)
def filter_reports(self):
self.sel.click(self._filter_crash_reports_button)
self.sel.wait_for_page_to_load(self.timeout)
# self.wait_for_element_present('css=div.page-heading > h2')
def click_first_signature(self):
self.wait_for_element_present(self._data_table_first_signature)
signature = self.sel.get_text(self._data_table_first_signature)
self.sel.click(self._data_table_first_signature)
self.sel.wait_for_page_to_load(self.timeout)
return signature
@property
def currently_selected_product(self):
return self.sel.get_selected_value(self._product_multiple_select)
@property
def product_list(self):
return self.sel.get_select_options(self._product_multiple_select)
class CrashStatsSearchResults(CrashStatsBasePage):
_product_select = 'id=product'
_version_select = 'id=version'
_os_select = 'id=platform'
_filter_crash_reports_button = 'id=query_submit'
def __init__(self, testsetup):
self.sel = testsetup.selenium
self.wait_for_element_present(self._product_select)
class CrashStatsPerActiveDailyUser(CrashStatsBasePage):
_product_select = 'id=daily_search_version_form_products'
def __init__(self, testsetup):
'''
Creates a new instance of the class and gets the page ready for testing
'''
self.sel = testsetup.selenium
@property
def product_select(self):
return self.sel.get_selected_value(self._product_select)
class CrashStatsTopCrashers(CrashStatsBasePage):
_product_header = 'css=h2 > span.current-product'
_product_version_header = 'css=h2 > span.current-version'
def __init__(self, testsetup):
self.sel = testsetup.selenium
@property
def product_header(self):
return self.sel.get_text(self._product_header)
@property
def product_version_header(self):
return self.sel.get_text(self._product_version_header)
class CrashStatsTopCrashersByUrl(CrashStatsBasePage):
_product_header = 'id=tcburl-product'
_product_version_header = 'id=tcburl-version'
def __init__(self, testsetup):
self.sel = testsetup.selenium
@property
def product_header(self):
return self.sel.get_text(self._product_header)
@property
def product_version_header(self):
return self.sel.get_text(self._product_version_header)
class CrashStatsTopCrashersByDomain(CrashStatsBasePage):
_product_header = 'id=tcburl-product'
_product_version_header = 'id=tcburl-version'
def __init__(self, testsetup):
self.sel = testsetup.selenium
@property
def product_header(self):
return self.sel.get_text(self._product_header)
@property
def product_version_header(self):
return self.sel.get_text(self._product_version_header)
class CrashStatsTopCrashersBySite(CrashStatsBasePage):
_product_header = 'id=tcburl-product'
_product_version_header = 'id=tcburl-version'
def __init__(self, testsetup):
self.sel = testsetup.selenium
@property
def product_header(self):
return self.sel.get_text(self._product_header)
@property
def product_version_header(self):
return self.sel.get_text(self._product_version_header)
class CrashStatsStatus(CrashStatsBasePage):
_page_header = 'css=h2:contains("Server Status")'
_at_a_glance_locator = 'css=div.title:contains("At a Glance")'
_graphs_locator = 'css=div.title:contains("Graphs")'
_latest_raw_stats = 'css=div.title:contains("Latest Raw Stats")'
def __init__(self, testsetup):
self.sel = testsetup.selenium
self.wait_for_element_present(self._page_header)
def at_a_glance(self):
if not self.sel.is_element_present(self._at_a_glance_locator):
raise Exception(self._at_a_glance_locator + ' is not available')
def graphs(self):
if not self.sel.is_element_present(self._graphs_locator):
raise Exception(self._graphs_locator + ' is not available')
def latest_raw_stats(self):
if not self.sel.is_element_present(self._graphs_locator):
raise Exception(self._latest_raw_stats + ' is not available')
Jump to Line
Something went wrong with that request. Please try again.