class Header2(BasePageWidget): """ represents header on hubs that use a javascripty dropdown menu to hold account links for dashboard, profile, messages and logout. """ def __init__(self, owner, locatordict={}): super(Header2,self).__init__(owner,locatordict) # load hub's classes Header_Locators = self.load_class('Header_Locators') # update this object's locator self.locators.update(Header_Locators.locators) # update the locators with those from the owner self.update_locators_from_owner() # setup page object's components self.login = Link(self,{'base':'login'}) self.register = Link(self,{'base':'register'}) self.logout = Link(self,{'base':'logout'}) self.details = Link(self,{'base':'details'}) self.dashboard = Link(self,{'base':'dashboard'}) self.messages = Link(self,{'base':'messages'}) self.profile = Link(self,{'base':'profile'}) # self.search = Search(self,'search') self._links = ['details','dashboard','messages','profile','logout'] # update the component's locators with this objects overrides self._updateLocators() def _checkLocatorsLoggedOut(self,widgets=None,cltype=""): widgets = [self.login] self._checkLocators(widgets=widgets,cltype='LoggedOut') def _checkLocatorsLoggedIn(self,widgets=None,cltype=""): widgets = [self.logout,self.dashboard, self.messages,self.profile] base = self.owner.find_element(self.locators['acctbase']) # hover mouse over the group manager toolbar to expand it actionProvider = ActionChains(self.owner._browser)\ .move_to_element(base) actionProvider.perform() # check for locators self._checkLocators(widgets=widgets,cltype='LoggedIn') def get_options_items(self): return self._links def goto_options_item(self,link): """this function does selenium specific stuff""" if not link in self._links: raise ValueError("invalid link name: '%s'",link) # hover mouse over the account toolbar to expand it # move the mouse to the correct link and click it menu = self.find_element(self.locators['acctbase']) loc = self.locators[link] menu_item = self.find_element(loc) self.logger.debug("moving mouse over account dropdown") self.logger.debug("clicking drowdown menu option '%s': %s" % (link,loc)) actionProvider = ActionChains(self.owner._browser)\ .move_to_element(menu)\ .move_to_element(menu_item)\ .click() actionProvider.perform() def goto_login(self): return self.login.click() def goto_register(self): return self.register.click() def goto_logout(self): lockey = 'logout' self.goto_options_item(lockey) # wait until the element is no longer visible (ie. the menu has closed) # before proceeding to the next task loc = self.locators[lockey] self.wait_until_not_present(locator=loc) def goto_myaccount(self): # deprecated function, use goto_dashboard() instead return self.goto_options_item('dashboard') def goto_dashboard(self): return self.goto_options_item('dashboard') def goto_messages(self): return self.goto_options_item('messages') def goto_profile(self): return self.goto_options_item('profile') def is_logged_in(self): """check if user is logged in, returns True or False""" # return not self.login.is_displayed() return self.logout.is_present() def get_account_number(self): """return the user's account number based on the "Username" url""" url = None # use dashboard instead of details because some hubs (like catalyzecare) # don't make details a link. url = self.dashboard.get_attribute('href') if url is None: raise RuntimeError("link '%s' has no href" \ % (self.details.locators['base'])) path = urlparse.urlsplit(url)[2] if not path: raise RuntimeError("url '%s' has no path" % (url)) # the url looks something like: # https://hubname.org/members/1234/dashboard matches = re.search("/members/(\d+)",path) if matches is None: raise RuntimeError("path '%s' does not contain an account number" \ % (path)) account_number = matches.group(1) return account_number
class GroupsWikiArticle(BasePageWidget): def __init__(self, owner, locatordict): super(GroupsWikiArticle,self).__init__(owner,locatordict) # load hub's classes GroupsWikiArticle_Locators = self.load_class('GroupsWikiArticle_Locators') TagsList = self.load_class('TagsList') # update this object's locator self.locators.update(GroupsWikiArticle_Locators.locators) # update the locators with those from the owner self.update_locators_from_owner() # setup page object's components self.pagetext = TextReadOnly(self,{'base':'pagetext'}) self.timestamp = TextReadOnly(self,{'base':'timestamp'}) self.tags = TagsList(self,{'base':'tags'}) self.authors = TextReadOnly(self,{'base':'authors'}) self.create = Link(self,{'base':'create'}) # update the component's locators with this objects overrides self._updateLocators() def _checkLocatorsWikiPage(self,widgets=None,cltype='WikiPage'): widgets = [self.pagetext,self.timestamp,self.tags] super(GroupsWikiArticle,self)._checkLocators(widgets,cltype) def _checkLocatorsKnowledgeBase(self,widgets=None,cltype='KnowledgeBase'): widgets = [self.pagetext,self.timestamp,self.tags,self.authors] super(GroupsWikiArticle,self)._checkLocators(widgets,cltype) def _checkLocatorsNewPage(self,widgets=None,cltype='NewPage'): widgets = [self.create] super(GroupsWikiArticle,self)._checkLocators(widgets,cltype) def get_tags(self): return self.tags.get_tags() def click_tag(self,tagname): return self.tags.click_tag(tagname) def get_page_text(self): return self.pagetext.value def get_authors(self): # e = self.find_element(self.locators['authors']) # authortext = re.sub(r'by ','',e.text) # authortext = re.sub(r', ',',',authortext) # authorlist = authortext.split(',') # return authorlist authorlist = [] authorElements = self.find_elements(self.locators['authorlink']) for authorElement in authorElements: authorlist.append(authorElement.text) return authorlist def is_created(self): return not self.create.is_present() def create_page(self): return self.create.click() def download_attachment(self,attachment): wikipagetext = self.find_element(self.locators['pagetext']) links = self.find_elements(self.locators['links'],wikipagetext) download_element = None for link in links: href = link.get_attribute('href') if re.search(attachment,href): download_element = link break else: raise NoSuchFileAttachmentError( "attachment not found on page: %s" % (attachment)) download_element.click() # this should probably be called is_file_downloadable # and is_file_attached, should just look to see if the # file is on the page. def is_file_attached(self,filepath): # filepath should be the full path to a real file on disk # because we download a copy and compare md5sum hashes to # see if that exact file is attached to the wiki. import os import md5 def md5sum_of_file(filename): f = open(filename, 'r') data = f.read() f.close() m = md5.new() m.update(data) digest = m.digest() return digest fname = os.path.basename(filepath) self.download_attachment(fname) # wait for file to be downloaded # FIXME: should consider using webdriver wait? # outfile = os.path.join(os.getcwd(),fname) outfile = os.path.join(self._po.downloaddir,fname) count = 0 while count < 5: time.sleep(2) if os.path.exists(outfile): break count = count + 1 # if the file wasn't downloaded, bail. if os.path.exists(outfile) == False: raise ValueError("file was not downloaded: %s" % (outfile)) # compare the md5sum of the file we uploaded # to the md5sum of the file we downloaded inDigest = md5sum_of_file(filepath) outDigest = md5sum_of_file(outfile) # remove the downloaded file os.remove(outfile) return (inDigest == outDigest)