def testTeardown(self): try: LOG.info("Destroying existing LUNs...") del self.luns except Exception as e: raise FailedProductException(e) self.driver.quit()
def isOpen(self, suppressLog=False): """ Check if page is loaded and visible by verifying if its unique components ('token') are present and visible on page. Can be overwritten in sub-classes for better page recognition by inspecting multiple page-specific components. """ if hasattr(self, 'token'): if not isinstance(self.token, list): tokens = [self.token] else: tokens = self.token isOpen = True for token in tokens: if not (token.isPresent() and token.isVisible()): isOpen = False break else: raise PageException(message=('%s: Page token is not defined.' % self.name), driver=self.driver, screenshotName=self.name + '.isOpen') if not suppressLog: LOG.l4('%s.isOpen(): %s' % (self.name, isOpen)) return isOpen
def _navigateToLUNSnapshotsPage(self, lunName): LOG.step('Navigating to LUN Snapshots page...') self.lunsPage.gridLUNs.clickLink(name=lunName, click={'name': lunName}) self.lunDetailsPage.waitUntilOpen() self.lunDetailsPage.tabSnapshots.click() self.lunSnapshotsPage.waitUntilOpen() LOG.info('Browser landed on LUN Snapshots page.')
def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.marscluster.snapshot.deleteAll() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.')
def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() self.marscluster.snapshot.deleteAll() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs & snapshots cleaned up.')
def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.')
def testTeardown(self): try: LOG.info("Destroying existing LUNs and igroups...") del self.igroups del self.luns except Exception, e: raise FailedProductException(e)
def submit(self): """ Submit dialog by clicking on button 'OK'. """ self.activePage.btnOK.waitUntilEnabled() self.activePage.btnOK.click() self.activePage.waitUntilClosed() LOG.l4('%s.submit()' % self.name)
def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns consistencyGroups = self.marscluster.cg.show(json=True) for consistencyGroup in consistencyGroups: self.marscluster.cg.delete(name=consistencyGroup['name']) self.assertFalse(self.marscluster.cg.show(json=True))
def _createInitiatorGroups(self, prefix, number, osType='vmware'): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype=osType.lower(), initiators=fictiveWWPN) groupNames = [group['name'] for group in self.marscluster.igroup.show(json=True)] LOG.info('Initiator group(s) created:', groupNames) return groupNames
def testSetup(self): LOG.step('Loading existing LUNs') self.luns = express.Luns(node=self.node, cleanup=True) self.igroups = express.Igroups(node=self.node, cleanup=self.cleanupMars) self.igroups.create(count=1, ostype='vmware', initiators=self.fcInitiators, prefix='ig_esx')
def getCSSProperty(self, propertyName): """ Return value of CSS property of base element (value of property consisted in attribute 'style'). Ex. <div style='display:none'>, where getCSSProperty(propertyName='display') will be 'none'. @param propertyName: Name of CSS property (ex. 'border-style', 'background-color'). @return: Value of CSS property (ex. 'solid dotted', 'red'). """ cssProperty = self.element.value_of_css_property(property_name=propertyName) LOG.l5("%s.getCSSProperty(%s): '%s'" % (self.name, propertyName, cssProperty)) return cssProperty
def waitUntilVisible(self): """ Wait until base element of component has become visible on web page. """ timeout = Timeout(timeout=self.driver.timeout, description='%s.waitUntilVisible(): Time out.' % self.name) while not self.isVisible(suppressLog=True): if timeout.exceeded(raiseException=False): raise ComponentFailedStateException(message='%s.waitUntilVisible(): Time out.' % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilVisible') time.sleep(self.driver.delay) LOG.l5('%s.waitUntilVisible()' % self.name)
def waitUntilAbsent(self): """ Wait until base element of component has completely disappeared from DOM. """ timeout = Timeout(timeout=self.driver.timeout, description='%s.waitUntilAbsent(): Time out.' % self.name) while self.isPresent(suppressLog=True): if timeout.exceeded(raiseException=False): raise ComponentFailedStateException(message='%s.waitUntilAbsent(): Time out.' % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilAbsent') time.sleep(self.driver.delay) LOG.l5('%s.waitUntilAbsent()' % self.name)
def waitUntilHidden(self): """ Wait until base element of component became invisible on web page; still, it's present in DOM, the same as isDisplayed() == False. """ timeout = Timeout(timeout=self.driver.timeout, description='%s.waitUntilHidden(): Time out.' % self.name) while self.isVisible(suppressLog=True): if timeout.exceeded(raiseException=False): raise ComponentFailedStateException(message='%s.waitUntilHidden(): Time out.' % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilHidden') time.sleep(self.driver.delay) LOG.l5('%s.waitUntilHidden()' % self.name)
def isVisible(self, suppressLog=False): """ Inspect if base HTML element is visible. Setting <... style='display:none>' hides element from visibility on web page, still retaining it in DOM. @return: True if base element of component visible, otherwise False. """ try: isVisible = self.element.is_displayed() except ComponentNotFoundException: isVisible = False if not suppressLog: LOG.l5('%s.isVisible(): %s' % (self.name, isVisible)) return isVisible
def getAttribute(self, attributeName, suppressLog=False): """ Returns attribute of HTML node of base WebElement of component such as 'id', 'class', 'data-mg-comp' etc. Do not confuse with Python object's attribute which __getattr__ above deals with. @param attributeName: Name of attribute of HTML node. @return: Attribute of HTML node. """ attribute = self.element.get_attribute(name=attributeName) if not suppressLog: LOG.l5("%s.getAttribute(attributeName='%s'): '%s'" % (self.name, attributeName, attribute)) return attribute
def test_delete_multi(self): """ Verify deletion of multiple unmapped initiator groups. """ initiatorGroupPrefix = 'IG' initiatorGroupNumber = 9 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting initiator groups in grid') self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames[:initiatorGroupNumber / 2]) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertTrue(len(selectedGroups) == initiatorGroupNumber / 2) LOG.info('Initiator group selected:', selectedGroups) LOG.step('Deleting and verifying initiator group has been deleted') self.initiatorGroupsPage.btnDelete.click() # Give some time to perform operation time.sleep(2) initiatorGroupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] self.assertTrue( len(initiatorGroupNames) == initiatorGroupNumber - (initiatorGroupNumber / 2)) for group in selectedGroups: self.assertFalse(group['initiator_group'] in initiatorGroupNames) LOG.info('Initiator group is not present:', group['initiator_group'])
def test_delete_not_available(self): """ Verify deletion is not available when no initiator groups selected in grid. """ initiatorGroupPrefix = 'ig' initiatorGroupNumber = 3 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Deselecting all initiator groups in grid') self.initiatorGroupsPage.gridInitiatorGroups.unselect( initiator_group=initiatorGroupNames) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertFalse(selectedGroups) LOG.info('Selected initiator groups:', selectedGroups) LOG.step("Verifying button 'Delete' is disabled in tool bar") self.assertFalse(self.initiatorGroupsPage.btnDelete.isEnabled()) LOG.info("Button 'Delete' is enabled:", self.initiatorGroupsPage.btnDelete.isEnabled())
def test_delete_single(self): """ Verify deletion of single unmapped initiator group. """ initiatorGroupPrefix = 'IG' initiatorGroupNumber = 5 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting initiator group in grid') self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames[0]) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertTrue(len(selectedGroups) == 1) self.assertTrue( selectedGroups[0]['initiator_group'] == initiatorGroupNames[0]) LOG.info('Initiator group selected:', initiatorGroupNames[0]) LOG.step('Deleting and verifying initiator group has been deleted') self.initiatorGroupsPage.btnDelete.click() initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupNumber - 1) self.assertFalse(initiatorGroupNames[0] in [group['name'] for group in initiatorGroups]) LOG.info( "Initiator group '%s' is not present:\n" % initiatorGroupNames[0].encode('utf-8'), initiatorGroups)
def open(self, wait=True): """ Open web page in browser. """ LOG.l4("%s.open(): URL='%s'" % (self.name, self.url)) self.webDriver.get(self.url) if wait: try: self.waitUntilOpen() except PageException: pass if self.validateLayout: self.doValidation() LOG.l4("%s.open(): Done." % self.name)
def waitUntilPresent(self): """ Wait until base element of component is present in DOM. Useful for checking if web page or component have been loaded. Note: Present <> enabled, element can easily be disabled still being present. """ timeout = Timeout(timeout=self.driver.timeout, description='%s.waitUntilPresent(): Time out.' % self.name) while not self.isPresent(suppressLog=True): if timeout.exceeded(raiseException=False): raise ComponentNotFoundException(message='%s.waitUntilPresent(): Time out.' % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilPresent') time.sleep(self.driver.delay) LOG.l5('%s.waitUntilPresent()' % self.name)
def takeScreenshot(self, name): """ Save screenshot of active web page to PNG file. @param name: Name of screenshot file. """ if LOG.getLogDir() is not None: logDirectory = LOG.getLogDir() else: logDirectory = os.getcwd() pathFileName = os.path.join( logDirectory, name + '.' + express.getUnixTime(formatstr='%Y%m%d_%H%M%S') + '.png') self.webDriver.save_screenshot(pathFileName) LOG.l4("Mangal.Driver: takeScreenshot(): Saved into '%s'" % pathFileName)
def suiteTeardown(self): self.driver.quit() LOG.info('Driver quit.') LOG.step('Deleting snapshots') snapshots = self.marscluster.snapshot.show(json=True) for snapshot in snapshots: self.marscluster.snapshot.delete(name=snapshot['name'], lun=snapshot['object']) self.assertFalse(self.marscluster.snapshot.show(json=True)) LOG.info('Snapshots deleted.') LOG.step('Destroying LUNs') luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.')
def waitUntilClosed(self): """ Customized solution doing inspection of absence or invisibility of page-specific components. """ timeout = Timeout(timeout=self.driver.timeout, description='%s.waitUntilClosed(): Time out.' % self.name) while self.isOpen(suppressLog=True): if timeout.exceeded(raiseException=False): raise PageException( message='%s.waitUntilClosed(): Time out.' % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilClosed') time.sleep(self.driver.delay) LOG.l5('%s.waitUntilClosed()' % self.name)
def waitUntilLoaded(self): """ Generic solution, may not be the best in any case. More robust approach is to verify presence/readiness of an element belonging to particular page. """ try: WebDriverWait( driver=self.webDriver, timeout=self.driver.timeout).until( lambda _: self.webDriver.execute_script( script='return document.readyState') == 'complete') except TimeoutException: raise PageException(message="%s.waitUntilLoaded: Time out." % self.name, driver=self.driver, screenshotName=self.name + '.waitUntilLoaded') LOG.l4('%s.waitUntilLoaded()' % self.name)
def _verifyClone(self, snapshotName, cloneName): luns = self.marscluster.lun.show(json=True) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['name'] == snapshotName ][0] clone = [ lun for lun in luns if (lun.get('parent-snapshot') == snapshotName and lun['name'] == cloneName) ][0] self.assertTrue(clone) self.assertTrue(clone['size'] == snapshot['lun-info']['size']) LOG.info("Clone size equal to snapshot size:", clone['size']) self.assertTrue(clone['parent'] == snapshot['object']) LOG.info("Cloned parent is original LUN:", clone['parent'])
def isPresent(self, suppressLog=False): """ Inspects if element is present (can be found) in DOM. Note: This is not equal to isVisible(), as element could be present in DOM but hidden. @return: True if present, otherwise False. """ try: # To determine if component is present, we just 'touch' it using __getattr__ above with # any attribute. if self.element.id(): isPresent = True except ComponentNotFoundException: isPresent = False if not suppressLog: LOG.l5('%s.isPresent(): %s' % (self.name, isPresent)) return isPresent
def callAttribute(self, *args, **kwargs): """ Translates attribute names to corresponding attribute calls. Takes care of named/unnamed parameters. @param args: Unnamed parameters (ex. 'admin' in send_keys('admin')). Optional. @param kwargs: Named parameters (ex. {'name': 'class'} in get_attribute(name='class')) """ timeout = Timeout(timeout=self.driver.timeout, description="%s.element.%s(%s, %s): selector='%s'. Time out." % (self.name, self.attributeName, args, kwargs, self.selector)) while True: if not timeout.exceeded(raiseException=False): if self.element is None: try: # Base web element of component, instance of WebDriver.WebElement. In # complex components, such as ComboBox or Grid, it is head element # which all other element/components are related to as children. self.element = self.webDriver.find_element_by_xpath(xpath=self.selector) except NoSuchElementException: self.element = None time.sleep(self.driver.delay) continue try: attribute = getattr(self.element, self.attributeName) # TODO: Investigate if there more elegant solutions are. if callable(attribute): if len(args) and len(kwargs): result = attribute(*args, **kwargs) elif len(args): result = attribute(*args) elif len(kwargs): result = attribute(**kwargs) else: result = attribute() else: result = attribute break except (StaleElementReferenceException, ElementNotVisibleException): self.element = None time.sleep(self.driver.delay) else: raise ComponentNotFoundException(message="%s.element.%s(%s, %s): selector='%s'. Time out." % (self.name, self.attributeName, args, kwargs, self.selector), driver=self.driver, takeScreenshot=False) LOG.l5('%s.element.%s(%s, %s)' % (self.name, self.attributeName, args, kwargs)) return result
def __init__(self, driverHostname, driverPort, browser, maximizeWindow=True): """ @param driverHostname: Host name on which instance of Remote WebDriver is running. Ex. 'mvm-win35' @param driverPort: Port number which WebDriver is communicating over. Ex. 4444 @param browser: Type of browser which is open by WebDriver: 'firefox' or 'chrome'. @param maximizeWindow: If True (default), maximize newly opened window in browser. """ LOG.info('Instantiating Mangal.Driver...') self.driverHostname = driverHostname self.driverPort = driverPort self.browser = browser self.timeout = 10 self.delay = .3 self._maximizeWindow = maximizeWindow self._start()