class LogIn: def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnSignUp(self): return self.driver.find_element_by_css_selector( "a[href='/registration-agent/']") def inpUsename(self): return self.driver.find_element_by_id("user_login") def inpPassword(self): return self.driver.find_element_by_id("user_pass") def btnLogIn(self): return self.driver.find_element_by_id("wp-submit") def go_to_sign_up(self): self.log.info("Execute method go_to_sign_up") self.btnSignUp().click() def log_in(self, username, password): wait_until(lambda: check_if_elem_exist(self.inpUsename), timeout=120) send_text(self.inpUsename(), username) send_text(self.inpPassword(), password) self.btnLogIn().click() wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_id("header-navigation")))
class RegistrationAgent: def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpFirstName(self): return self.driver.find_element_by_css_selector( "input[name='Fname_22']") def inpLastName(self): return self.driver.find_element_by_css_selector( "input[name='Lname_23']") def inpCEA(self): return self.driver.find_element_by_css_selector( "input[name='Textbox_24']") def inpMobileNumber(self): return self.driver.find_element_by_css_selector( "input[name='Mobile_25']") def btnNext(self): return self.driver.find_element_by_css_selector("input[value='Next']") def sign_up(self, firstName, lastname, CEA, mobile): self.log.info("Execute method sign_up with parameters" " firstName={}, lastName={}, CEA={}, mobile={}".format( firstName, lastname, CEA, mobile)) send_text(self.inpFirstName(), firstName) send_text(self.inpLastName(), lastname) send_text(self.inpCEA(), CEA) send_text(self.inpMobileNumber(), mobile) self.log.screenshot("Entered info") self.btnNext().click() wait_until(lambda: not check_if_elem_exist(self.inpFirstName))
class HomePage(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def go_to_sign_up(self): """ Click on sign up """ self.log.info("Go to sign up page") if not self.btnSignUp().is_displayed(): self.btnOpenMenu().click() self.btnSignUpMobile().click() else: self.btnSignUp().click() time.sleep(1) def go_to_log_in(self): """ Click on log in """ self.log.info("Go to log in page") if not self.btnLogIn().is_displayed(): time.sleep(2) self.btnOpenMenu().click() wait_until(lambda: check_if_elem_exist(self.btnLogInMobile), timeout=20) scroll_element_to_center(self.driver, self.log, self.btnLogInMobile()) self.btnLogInMobile().click() else: self.btnLogIn().click() time.sleep(1)
class UserProfile: def __init__(self, driver): self.driver = driver self.log = Log(driver) def aEditInfo(self): return self.driver.find_element_by_css_selector( "a[href='/user-profile/?a=edit']") def inpFirstName(self): return self.driver.find_element_by_id('first_name') def inpLastName(self): return self.driver.find_element_by_id('last_name') def inpEmail(self): return self.driver.find_element_by_id('user_email') def inpMobile(self): return self.driver.find_element_by_id('mobile_number') def btnSubmit(self): return self.driver.find_element_by_css_selector("input[name='submit']") def edit_info(self, firstName, lastName, email, mobile): self.aEditInfo().click() send_text(self.inpFirstName(), firstName, mode="update") send_text(self.inpLastName(), lastName, mode="update") send_text(self.inpEmail(), email, mode="update") send_text(self.inpMobile(), mobile, mode="update") self.log.screenshot() self.btnSubmit().click() time.sleep(3)
def __init__(self, driver="Firefox", mobileToTest=None, orientation="Portrait"): """ Creates driver and hold arguments for mobileToTest and orientation. If mobileToTest is not forwarded driver will test like on computer. Another way to forward this parameters are from command line with arguments --browser, --config, --mobile, --orientation. Example of command: python Test.py --browser=Firefox --config=Case1 --mobile="galaxyS9/S9+" --orientation=Landscape :param driver: Driver name :type driver: str :param mobileToTest: Key value from MobileTesting.json file from Configuration folder :type mobileToTest: str :param orientation: Used only if mobileToTest is forwarded. Possible values: Portrait and Landscape :type orientation: str """ if platform.system() in "Windows": from ctypes import windll if windll.user32.BlockInput(True) == 0: raise Exception("Not running script as admin") if is_forwarded("browser") is not None: driver = is_forwarded("browser") DriverData.driverName = driver if is_forwarded("mobile") is not None: mobileToTest = is_forwarded("mobile") if mobileToTest is not None: DriverData.mobile = True if is_forwarded("orientation") is not None: orientation = is_forwarded("orientation") DriverData.mobileToTest = mobileToTest DriverData.orientation = orientation self.driver = self._create_driver(driver, mobileToTest, orientation) self.log = Log(self.driver) if mobileToTest is not None: self.log.info( "Driver to create is={}, on mobile={} and orientation={}". format(driver, mobileToTest, orientation)) else: self.log.info( "Driver to create is={}. Testing on desktop computer".format( driver))
class Dashboard: def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnCreateNewTour(self): #return self.driver.find_element_by_css_selector("a[href*='create-new-virtual-tour']") return self.driver.find_element_by_css_selector("img[src*='create1']") def btnViewEditTour(self): #return self.driver.find_element_by_css_selector("a[href*='edit-scenes']") return self.driver.find_element_by_css_selector("img[src*='edittour1']") def btnEditProfile(self): return self.driver.find_element_by_css_selector("img[src*='editprofile1']") def create_new_tour(self): """ Click on create new tour """ self.log.info("Execute method create_new_tour") wait_until(lambda: check_if_elem_exist(self.btnCreateNewTour), timeout=30) scroll_element_to_center(self.driver, self.log, self.btnCreateNewTour()) wait_until(lambda: check_if_elem_exist(self.btnCreateNewTour)) time.sleep(5) self.btnCreateNewTour().click() self.log.info("Create new tour button clicked") wait_until(lambda: check_if_elem_exist(BasicInformationTour(self.driver).inpTitle), timeout=30, errorMessage="Create new tour not opened") def view_edit_tour(self): """ Click on view edit tour """ self.log.info("Go to view/edit tour") wait_until(lambda: check_if_elem_exist(self.btnViewEditTour), timeout=30) # self.driver.execute_script("arguments[0].scrollIntoView();", self.btnViewEditTour()) # time.sleep(5) # self.btnViewEditTour().click() self.driver.execute_script("arguments[0].click();", self.btnViewEditTour()) wait_until(lambda: not check_if_elem_exist(self.btnViewEditTour), timeout=30) def go_to_edit_profile(self): """ Click on edit profile """ self.log.info("Go to edit profile") self.btnEditProfile().click() time.sleep(2)
class EditProfile: def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpContactName(self): return self.driver.find_element_by_id("contact_name") def inpContactDetail(self): return self.driver.find_element_by_id("contact_main") def inpEmail(self): return self.driver.find_element_by_id("contact_alt") def txtDescription(self): return self.driver.find_element_by_css_selector("textarea[name='description']") def btnSave(self): return self.driver.find_element_by_id("submit") def edit_profile(self, name, contactDetail, email, description): """ Insert data for editing profile :param name: :param contactDetail: :param email: :param description: """ self.log.info("Execute method edit_profile with parameters name={}, contactDetail={}, email={}," " description={}".format(name, contactDetail, email, description)) self.inpContactName().send_keys(name) self.inpContactDetail().send_keys(contactDetail) self.inpEmail().send_keys(email) self.txtDescription().send_keys(description) time.sleep(0.5) self.log.screenshot("Data is entered") self.btnSave().click() self.log.info("Button save is clicked") time.sleep(2)
from Lib.common.ConfigLoader import ConfigLoader from Lib.common.DriverData import DriverData from Lib.common.Log import Log from Lib.temasekproperties.HomePage import HomePage from Lib.temasekproperties.Listings import Listings from Lib.temasekproperties.LogIn import LogIn from Lib.temasekproperties.Resources import Resources cl = ConfigLoader() createDriver = DriverData() driver = createDriver.get_driver() driver.get("https://temasekproperties.com/wp-login.php") log = Log(driver) li = LogIn(driver) li.log_in("TestBS", "test123") hp = HomePage(driver) hp.go_to_resources_booking() #hp.go_to_listings() rb = Resources(driver) #l.search_for("Derbyshire") rb.book("Central - Newton", "Derbyshire #22-01") bookedFor = rb.booking_steps() hp.go_to_resources_booked() rb.check_if_exist("6 Derbyshire #22-01", bookedFor)
class BasicInformationTour: def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpTitle(self): return self.driver.find_element_by_id("title") def inpAddress(self): return self.driver.find_element_by_id("address") def inpWatermarkText(self): return self.driver.find_element_by_id("watermark") def txtDescription(self): return self.driver.find_element_by_id("formGroupExampleInput7") def rbtnPublicAccess(self, answer): radio_btns = self.driver.find_element_by_class_name("check-box_radio") return radio_btns.find_element_by_xpath( "//span[contains(text(),'{}')]/preceding-sibling::input".format( answer)) def btnSubmit(self): return self.driver.find_element_by_id("btnSubmit") def check_insert_basic_info_successfully(self): try: self.driver.find_element_by_xpath( "//h3[contains(text(),'upload your scenes')]") return True except: return False def set_basic_info(self, title, address, description, watermark="", publicAccess=True, mode="set"): """ Insert basic info for creating new tour :param title: Title of tour :type title: str :param address: Tour address :type address: str :param description: Tour description :type description: str :param watermark: Watermark :type watermark: str :param publicAccess: Choose radio button for public access :type publicAccess: bool :param mode: Possible values are set or update :type mode: str """ self.log.info( "Execute method set_basic_info with parameters title={}, address={}, description={}," " watermark={}, publicAccess={}, mode={}".format( title, address, description, watermark, publicAccess, mode)) if title: wait_until(lambda: check_if_elem_exist(self.inpTitle), timeout=30) send_text(self.inpTitle(), title, mode=mode) if address: send_text(self.inpAddress(), address, mode=mode) if watermark: send_text(self.inpWatermarkText(), watermark, mode="update") if publicAccess: self.rbtnPublicAccess("Yes").click() else: self.rbtnPublicAccess("No").click() if description: send_text(self.txtDescription(), description, mode=mode) self.log.screenshot("Data entered. Click on button submit") self.btnSubmit().click() wait = WebDriverWait(self.driver, 60) wait.until( expected_conditions.visibility_of_element_located( (By.CSS_SELECTOR, "div[class*='qq-upload-button']"))) self.log.info("Submit done")
class Listings(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def aPurchase(self): return self.driver.find_element_by_css_selector( "a[class='edd-add-to-cart button blue edd-submit edd-has-js']") def aCheckout(self): return self.driver.find_element_by_css_selector( "a[href='https://temasekproperties.com/checkout/']") def inpEmail(self): return self.driver.find_element_by_css_selector( "input[id='edd-email']") def inpFirstName(self): return self.driver.find_element_by_css_selector( "input[id='edd-first']") def inpLastName(self): return self.driver.find_element_by_css_selector("input[id='edd-last']") def btnFinalPurchase(self): return self.driver.find_element_by_id("edd-purchase-button") def aPlay(self): return self.driver.find_element_by_css_selector("a[id='button-play']") def canvas(self): return self.driver.find_element_by_tag_name("canvas") def ddlistFloor(self): return self.driver.find_element_by_css_selector( "div[class='gui-floor hasHover open']") def lstFloor(self): return self.ddlistFloor().find_element_by_css_selector( "div[class='container']") def btnFloor(self): return self.driver.find_element_by_css_selector("div[class*='gui-floor hasHover']").\ find_element_by_css_selector("i[class='icon icon-dpad-up']") def btnPayPal(self): return self.driver.find_element_by_css_selector( "span[class='paypal-button-content']") def inpSearch(self): return self.driver.find_element_by_css_selector( "input[placeholder='Search …']") def btnSearch(self): return self.driver.find_element_by_css_selector( "input[name='_sf_submit']") def get_all_listings(self): root = self.driver.find_element_by_css_selector( "div[class='edd_downloads_list edd_download_columns_3']") allDivs = root.find_elements_by_tag_name("div") allListing = [] for div in allDivs: if div.get_attribute("class") == "edd_download" or \ div.get_attribute("class") == "edd_download download_bought": allListing.append(div) return allListing def change_page(self, page): self.log.info( "Execute method change_page with parameter page={}".format(page)) if page != 1: self.driver.get( "https://temasekproperties.com/listings/?sf_paged={}".format( page)) self.log.screenshot("Page opened") def open_listing_by_index(self, index): self.log.info( "Execute method open_listing_by_index with parameter index={}". format(index)) self.get_all_listings()[int(index) - 1].find_element_by_tag_name("a").click() wait_page_load(self.driver) def purchase_listing(self, payment, email, firstName, lastName, payPalEmail, payPalPassword): self.log.info("Execute method purchase_listing") time.sleep(5) wait_page_load(self.driver) wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "div[class='edd_price_options edd_single_mode']"))) #formElement = self.driver.find_element_by_css_selector("form[id='edd_purchase_9273']") #edd_download_purchase_form edd_purchase_9273 formElement = self.driver.find_element_by_css_selector( "div[class='edd_price_options edd_single_mode']") purchases = formElement.find_elements_by_css_selector( "span[class='edd_price_option_name']") for purchase in purchases: if purchase.text == payment: purchase.find_element_by_xpath('..').click() time.sleep(1) self.log.screenshot("Selected payment={}".format(payment)) break self.aPurchase().click() time.sleep(5) self.aCheckout().click() send_text(self.inpEmail(), email, mode="update") send_text(self.inpFirstName(), firstName, mode="update") send_text(self.inpLastName(), lastName, mode="update") self.log.screenshot("Inserted email, firstname, lastname") self.btnFinalPurchase().click() wait_until(lambda: check_if_elem_exist(self.btnPayPal), 30) time.sleep(10) self.btnPayPal().click() wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_id("payment_type_paypal")), timeout=60) self.driver.find_element_by_id("payment_type_paypal").click() self.driver.find_element_by_css_selector( "input[name='unified_login.x']").click() #paypal window is opened self.log.info("Add PayPal credentials") wait_until(lambda: check_if_elem_exist(self.inpPayPalEmail), timeout=60) send_text(self.inpPayPalEmail(), payPalEmail, mode="update") send_text(self.inpPayPalPass(), payPalPassword, mode="update") self.log.screenshot("Credentials for PayPal are entered") self.btnLogInPayPal().click() wait_until(lambda: check_if_elem_exist(lambda: self.driver. find_element_by_css_selector( "input[name='submit.x']"))) self.driver.find_element_by_css_selector( "input[name='submit.x']").click() wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_xpath( "//h1[contains(text(),'{}')]".format( "Your purchase was successful")))) self.log.screenshot("Listing purchased") def play(self): self.driver.switch_to.frame(self.driver.find_element_by_id("frame_me")) time.sleep(5) wait_until(lambda: check_if_elem_exist(lambda: self.driver. find_element_by_css_selector( "a[id='button-play']")), timeout=60) interractable = True while (interractable): try: self.aPlay().click() interractable = False except Exception as ex: #print(str(ex)) if "element not interactable" in str(ex): pass interractable = False # ac = ActionChains(self.driver) # ac.click(self.aPlay()) # ac.perform() #self.driver.execute_script("arguments[0].click();", self.aPlay()) wait_until(lambda: "display: none;" in self.driver.find_element_by_id( "gui-loading").get_attribute("style"), timeout=60) time.sleep(20) self.driver.find_element_by_tag_name("body").click() def moveListing(self, numberOfMoves, right=True): # for i in range(numberOfMoves): # time.sleep(6) # ac = ActionChains(self.driver) # ac.move_to_element(self.canvas()) # ac.move_by_offset(100, 0) # ac.move_by_offset(100, 0) # ac.click_and_hold() # if right: # ac.move_by_offset(-1*int(self.canvas().size["width"]/8), 0) # else: # ac.move_by_offset(int(self.canvas().size["width"]/8), 0) # ac.release() # ac.perform() # time.sleep(2) # self.log.screenshot("nakon pomeranje") scroll_element_to_center(self.driver, self.log, self.canvas()) for i in range(numberOfMoves): time.sleep(6) ActionChains(self.driver).move_to_element(self.canvas()).perform() ActionChains(self.driver).click_and_hold().perform() if right: ActionChains(self.driver).move_by_offset( -1 * int(self.canvas().size["width"] / 8), 0).perform() else: ActionChains(self.driver).move_by_offset( int(self.canvas().size["width"] / 8), 0).perform() ActionChains(self.driver).release().perform() time.sleep(2) self.log.screenshot("Listing moved") def choose_floor(self, floor): try: time.sleep(5) wait_until(lambda: check_if_elem_exist(self.btnFloor), timeout=60) self.btnFloor().click() wait_until(lambda: check_if_elem_exist(self.ddlistFloor), timeout=10) self.lstFloor().find_element_by_css_selector( "div[data-index='{}']".format(floor - 1)).click() wait_until(lambda: not check_if_elem_exist(self.ddlistFloor), timeout=10) return True except Exception as ex: return False def search_for(self, searchFor): send_text(self.inpSearch(), searchFor) self.btnSearch().click() wait_page_load(self.driver)
class UploadedScenesTour(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpSceneTitle(self, index): return self.driver.find_elements_by_css_selector( "input[id='scence-title']")[index] def btnNext(self): return self.driver.find_element_by_css_selector( "input[value='Next >>']") def btnDeleteSceneOk(self): return self.driver.find_element_by_css_selector( "button[class='ajs-button ajs-ok']") def insert_scenes_title(self, scenes): """ Insert scene title and click on next button. :param scenes: For given list of scenes go through each and insert title :type scenes: list[Scene] """ self.log.info( "Execute method insert_scenes_title with parameter scenes={}". format(''.join(scenes.__repr__()))) foundScenes = self.driver.find_elements_by_css_selector( "div[class*='scence-image ']") for picture in scenes: for scene in foundScenes: if scene.find_element_by_tag_name( "p").text == picture.fileName: #inputTitle = scene.find_element_by_id("scence-title") inputTitle = scene.find_element_by_css_selector( "input[id*='scence-title']") inputTitle.send_keys(picture.title) time.sleep(1) break time.sleep(1) self.btnNext().click() wait_until(lambda: check_if_elem_exist( ConnectScenesTour(self.driver).btnHotSpot), timeout=30, period=2) self.log.screenshot("Button next executed") def delete_uploaded_scene(self, title): """ Delete uploaded scenes with title. :param title: Title of scene to delete :type title: str """ self.log.info( "Execute method delete_uploaded_scene with parameter={}".format( title)) numberOfScenesBeforeDelete = len(self.get_uploaded_scenes()) uploadedScenes = self.driver.find_elements_by_css_selector( "div[class^='scence-image col-lg-12']") foundScene = False for scene in uploadedScenes: current_title = scene.find_element_by_css_selector( "input[id*='scence-title']").get_attribute("value") if current_title == title: self.log.info("Delete scene with title={}".format(title)) scroll_element_to_center( self.driver, self.log, scene.find_element_by_css_selector( "div[class='icon-delete']")) scene.find_element_by_css_selector( "div[class='icon-delete']").click() wait_until(lambda: check_if_elem_exist(self.btnDeleteSceneOk), timeout=10) wait_until(expected_conditions.alert_is_present, timeout=10) self.btnDeleteSceneOk() self.btnDeleteSceneOk().click() try: wait_until( lambda: not check_if_elem_exist(self.btnDeleteSceneOk), timeout=10) except Exception as ex: self.btnDeleteSceneOk().click() wait_until( lambda: numberOfScenesBeforeDelete - 1 == len( self.get_uploaded_scenes()), 30) wait_until(lambda: check_if_elem_exist( UploadScenesTour(self.driver).btnUpload), timeout=30, period=2) self.log.screenshot("Scene {} deleted".format(title)) foundScene = True break if not foundScene: raise Exception("Scene with title {} not found".format(title)) def get_uploaded_scenes(self): """ Get current uploaded scenes :return: title of all uploaded scenes """ self.log.info("Execute method get_uploaded_scenes") titles = [] scenes = self.driver.find_elements_by_css_selector( 'input[id*="scence-title"]') for scene in scenes: titles.append(scene.get_attribute('value')) self.log.info("Uploaded scenes are={}".format(titles)) return titles
class ConnectScenesTour(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnHotSpot(self): return self.driver.find_element_by_css_selector( "img[src*='icon-room.png']") def btnInfo(self): return self.driver.find_element_by_css_selector( "img[src*='icon-info.png']") def inpInfoTitle(self): return self.driver.find_element_by_css_selector( "input[id='info_title']") def inpInfoDetail(self): return self.driver.find_element_by_css_selector("div[id='detailBox']") def inpInfoUrl(self): return self.driver.find_element_by_css_selector("input[id='info_url']") def btnInfoSave(self): return self.driver.find_element_by_css_selector( "input[onclick='ajaxInfoHS()']") def btnDefaultView(self): return self.driver.find_element_by_css_selector( "a[class='button-set-default']") def btnPanToView(self): return self.driver.find_element_by_css_selector( "a[class='button-default-vew']") def btnViewTour(self): return self.driver.find_element_by_css_selector( "a[class='button-hotspot']") def btnMoveRight(self): return self.driver.find_element_by_css_selector( "img[src*='right-arrow']") def btnZoomOut(self): return self.driver.find_element_by_css_selector( "img[src*='minus.svg']") def tourImage(self): return self.driver.find_element_by_class_name("pnlm-dragfix") def btnRighRotate(self): return self.driver.find_element_by_css_selector( "img[src*='right-arrow.svg']") def btnUpRotate(self): return self.driver.find_element_by_css_selector( "img[src*='up-arrow.svg']") def btnDownRotate(self): return self.driver.find_element_by_css_selector( "img[src*='down-arrow.svg']") def btnLeftRotate(self): return self.driver.find_element_by_css_selector( "img[src*='left-arrow.svg']") def btnDeleteHotSpot(self): wait_until(lambda: check_if_elem_exist(self.divHotSpotMenu), timeout=10) return self.divHotSpotMenu().find_element_by_css_selector( "a[id*='hotSpotDelete']") def btnEditHotSpot(self): return self.divHotSpotMenu().find_element_by_css_selector( "a[id*='hotSpotEdit']") def btnGoToHotSpot(self): return self.divHotSpotMenu().find_element_by_css_selector( "a[id*='hotSpotGoto']") def btnSaveHotSpot(self): return self.driver.find_element_by_css_selector( "div[style='text-align: center;']").find_element_by_id("submit") def btnSaveEditedHotSpot(self): return self.driver.find_element_by_css_selector( "input[onclick='ajaxEditHotspot()']") def btnPublish(self): return self.driver.find_element_by_css_selector( "input[value='Publish']") def btnChangeTheme(self): return self.driver.find_element_by_css_selector( "a[class='button-changetheme']").find_element_by_tag_name("img") def imgThemeToSelect(self, number): return self.driver.find_elements_by_css_selector( "div[class*='thumbnail']")[number - 1] def btnSelectTheme(self): return self.driver.find_element_by_css_selector( "input[value='Choose Theme']") def divHotSpotMenu(self): allMenus = self.driver.find_elements_by_css_selector( "div[class='hotSpotMenu']") for menu in allMenus: if "visible;" in menu.get_attribute("style"): return menu def btnSaveInfo(self): return self.driver.find_element_by_css_selector( "input[onclick='ajaxInfoHS()']") def imgArrowType(self, number): return self.driver.find_element_by_css_selector("div[class='type-hotSpots']")\ .find_element_by_css_selector("img[src*='{}.png']".format(number)) ############################################################# def choose_theme(self, number): """ Choose theme by number [1..4] :param number: Ordinal number of shown themes :type number: int [1..4] """ self.log.info( "Execute method choose_theme with parameter number={}".format( number)) wait_until(lambda: check_if_elem_exist(self.btnChangeTheme), timeout=10) scroll_element_to_center(self.driver, self.log, self.btnChangeTheme()) time.sleep(3) self.btnChangeTheme().click() wait_until( lambda: check_if_elem_exist(lambda: self.imgThemeToSelect(number)), timeout=30) newTheme = self.imgThemeToSelect(number) themeSrc = newTheme.find_element_by_tag_name("img").get_attribute( "src") newTheme.click() wait_until(lambda: "selected" in self.imgThemeToSelect(number). get_attribute("class"), timeout=5) self.log.screenshot("Theme is selected") self.btnSelectTheme().click() wait_until( lambda: self.btnChangeTheme().get_attribute("src") == themeSrc, timeout=20) self.log.screenshot("Theme is updated") def add_button_to_center(self, hotSpot=True): time.sleep(1) wait_until(lambda: "none" in self.driver.find_element_by_id( "themeLabelHide").get_attribute("style"), timeout=30) if DriverData.driverName == "Firefox": self._add_button_to_center_firefox(hotSpot) elif DriverData.driverName == "Chrome": self._add_button_to_center_chrome(hotSpot) elif DriverData.driverName == "Safari": self._add_button_to_center_safari(hotSpot) def _add_button_to_center_firefox(self, hotSpot): """ Puts hotSpot or info in center of scene. :param hotSpot: True if hotSpot is added, False if info is added :type hotSpot: bool """ self.log.info("Execute method _add_button_to_center") if hotSpot: button = self.btnHotSpot else: button = self.btnInfo scroll_element_to_center(self.driver, self.log, button()) buttonSize = button().size ac = ActionChains(self.driver) time.sleep(3) ac.move_to_element_with_offset(button(), buttonSize["width"] / 2, buttonSize["height"] / 2).perform() time.sleep(3) ac.click_and_hold().perform() tourSize = self.tourImage().size time.sleep(3) #scroll_element_to_viewPoint_with_selenium(self.driver, self.tourImage()) scroll_element_to_viewpoint_top(self.log, self.driver, self.tourImage()) time.sleep(1) move_mouse_to_middle_of_browser(self.log, self.driver) time.sleep(1) ac.move_to_element_with_offset(self.tourImage(), tourSize["width"] / 2, tourSize["height"] / 2).perform() ac.release().perform() time.sleep(1) self.log.screenshot("Button is added") def _add_button_to_center_chrome(self, hotSpot): """ Puts hotSpot or info in center of scene. :param hotSpot: True if hotSpot is added, False if info is added :type hotSpot: bool """ self.log.info("Execute method _add_button_to_center") if hotSpot: button = self.btnHotSpot else: button = self.btnInfo move_mouse_to_element(self.driver, self.log, button()) time.sleep(1) pyautogui.mouseDown(duration=1) move_mouse_to_element(self.driver, self.log, self.tourImage()) time.sleep(1) pyautogui.mouseUp(duration=1) time.sleep(1) self.log.screenshot("Button is added") def _add_button_to_center_safari(self, hotSpot): time.sleep(3) self.log.info("Execute method _add_button_to_center") if hotSpot: button = self.btnHotSpot else: button = self.btnInfo oneScrollPixels = self._get_hotSpot_scroll_pixels(hotSpot) scroll_element_to_center(self.driver, self.log, button()) fromLocation = get_location(self.driver, button()) toLocation = get_location(self.driver, self.tourImage()) scrollToBottom = self.driver.execute_script( "return window.pageYOffset") + int( self.driver.execute_script( "return window.innerHeight")) - fromLocation["y"] - 25 # if not hotSpot: # scrollToBottom -= 37 moveFor = toLocation["y"] + self.tourImage().size["height"] / 2 - ( self.driver.execute_script("return window.pageYOffset") + int(self.driver.execute_script("return window.innerHeight")) ) + int(self.driver.execute_script("return window.innerHeight") / 2) numberOfMoves = int(moveFor / oneScrollPixels) wantedX = toLocation["x"] + int(self.tourImage().size["width"] / 2) wantedY = toLocation["y"] + int(self.tourImage().size["height"] / 2) currentX = fromLocation["x"] + int(button().size["width"] / 2) if numberOfMoves % 2 != 0: currentX += 10 currentY = fromLocation["y"] + int( button().size["height"] / 2) + scrollToBottom + oneScrollPixels * numberOfMoves x = wantedX - currentX y = wantedY - currentY time.sleep(1) ac = ActionChains(self.driver) ac.move_to_element(button()).click_and_hold() self.drag_with_hotspot_safari(ac, scrollToBottom, numberOfMoves, x, y) ActionChains(self.driver).click().perform() def _get_hotSpot_scroll_pixels(self, hotSpot): """ For how many pixels to move hotSpot so that scroll is activated :param hotSpot: HotSpot of info button. True if hotSpot. :type hotSpot: bool :return: Pixels to scroll for """ if hotSpot: element = self.btnHotSpot() else: element = self.btnInfo() startHidenPixels = get_hidden_pixels(self.driver) scroll_element_to_center(self.driver, self.log, element) action_chains = ActionChains(self.driver) hiddenPixels = get_hidden_pixels(self.driver) fromLocation = get_location(self.driver, element) action_chains.move_to_element(element) action_chains.click_and_hold() scrollFor = self.driver.execute_script( "return window.pageYOffset") + int( self.driver.execute_script( "return window.innerHeight")) - fromLocation["y"] - 25 action_chains.move_by_offset(0, scrollFor) #action_chains.move_by_offset(10, 0) # action_chains.move_by_offset(10, 0) # action_chains.move_by_offset(-10, 0) action_chains.move_by_offset(0, -scrollFor) action_chains.release() action_chains.perform() hiddenPixelsAfter = get_hidden_pixels(self.driver) scrolledPixels = hiddenPixelsAfter - hiddenPixels self.driver.execute_script("scroll(0,{})".format(startHidenPixels)) return scrolledPixels def drag_with_hotspot_safari(self, act, scrollToBottom, numberOfMoves, x, y): """ Drag hotspot in safari with action chains :param act: ActionChains :param scrollToBottom: Pixels to scroll hotSpot so that scroll is activated :param numberOfMoves: Number of moves to get tour on center :param x: X location on center of tour :param y: Y location on center of tour """ act.move_by_offset(0, scrollToBottom) moveToSide = 10 for i in range(numberOfMoves): act.move_by_offset(moveToSide, 0) moveToSide *= -1 act.move_by_offset(x, y) act.perform() def _add_info_data(self, title, detail, url, mode="set"): """ After info button is added to scene, insert information. :param mode: Possible values are set or update :type mode: str """ self.log.info("Execute method _add_info_data with parameters " "title={}, detail={}, url={}".format(title, detail, url)) send_text(self.inpInfoTitle(), title, mode) send_text(self.inpInfoDetail(), detail, mode) send_text(self.inpInfoUrl(), url, mode) self.log.screenshot("Information is added") self.btnSaveInfo().click() time.sleep(3) def get_hotspot_from_center(self, center=True): """ Return hotspot if on center or raise exception """ hotSpotFound = None for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size tourSceneCenter = self.tourImage().size["width"] / 2 self.log.info( "Check if hotspot with x location={} is on center={}". format(hotSpotLocationWidth, tourSceneCenter)) limit = 50 if (hotSpotLocationWidth > tourSceneCenter - limit and hotSpotLocationWidth < tourSceneCenter + limit): #allowed error of 50 pixels self.log.screenshot("Hotspot is in center") hotSpotFound = hotSpot return hotSpot except Exception as ex: self.log.info(str(ex)) if hotSpotFound is None: raise Exception("HotSpot is not in center") def get_hotspot_closer_to_center(self, center=True): """ Return hotspot if on center or raise exception """ hotSpotFound = None for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size tourSceneCenter = self.tourImage().size["width"] / 2 self.log.info( "Check if hotspot with x location={} is on center={}". format(hotSpotLocationWidth, tourSceneCenter)) limit = 50 if (hotSpotLocationWidth > tourSceneCenter - limit and hotSpotLocationWidth < tourSceneCenter + limit): #allowed error of 50 pixels self.log.screenshot("Hotspot is in center") hotSpotFound = hotSpot return hotSpot except Exception as ex: self.log.info(str(ex)) if hotSpotFound is None: raise Exception("HotSpot is not in center") def rotate(self, right, clickNumber, useArrows): """ Rotate scene to right or left clickNumber of times. :param right: True for moving to right, False for moving to left :type right: bool :param clickNumber: Number of times to click on arrow :type clickNumber: int """ wait_until(self.btnLeftRotate) self.log.info( "Execute method rotate with parameters right={}, clickNumber={}". format(right, clickNumber)) if clickNumber != 0: if not useArrows: if DriverData.driverName == "Chrome" and DriverData.mobile is False: for i in range(clickNumber): time.sleep(5) # move_to_element_chrome(self.driver, self.tourImage(), 100) pyautogui.mouseDown() #moveFor = int(int(self.tourImage().size["width"]) / 58) moveFor = int(int(self.tourImage().size["width"]) / 8) if right: pyautogui.moveRel(moveFor * -1, 0, 1) else: pyautogui.moveRel(moveFor, 0, 1) pyautogui.mouseUp() time.sleep(5) else: for i in range(clickNumber): time.sleep(5) ac = ActionChains(self.driver) ac.move_to_element(self.tourImage()) ac.click_and_hold() #moveFor = int(int(self.tourImage().size["width"])/58) moveFor = int(int(self.tourImage().size["width"]) / 8) if right: ac.move_by_offset(moveFor * -1, 0) else: ac.move_by_offset(moveFor, 0) ac.release() ac.perform() time.sleep(5) else: if right: button = self.btnRighRotate else: button = self.btnLeftRotate for i in range(clickNumber): time.sleep(1.5) wait_until(lambda: check_if_elem_exist(button), timeout=10) button().click() time.sleep(1.5) self.log.screenshot("Rotate is done") def rotate2(self, move, useArrows, view): """ Rotate scene to right or left clickNumber of times. :param move: List of strings where to move. Order is important. Example ["left:2","right:5","up:1","down:1"] :type move: list """ self.log.info( "Execute method rotate with parameters move={}".format(move)) for move_to in move: move_number = move_to.split(":") move_where = move_number[0] move_number = int(move_number[1]) if not view: self.move(move_where, move_number, useArrows, view) else: self.view_tour(move_where, move_number) self.log.screenshot("Rotate is done") def where_to_move_edit_and_view(self): self.log.info("Execute method _check_hotSpot_on_view") for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size browserX = self.tourImage().size["width"] self.log.info( "Check if hotspot with x location={} is on view={}".format( hotSpotLocationWidth, browserX)) if hotSpotLocationWidth > 0 and browserX / 2 > hotSpotLocationWidth - 125 and browserX / 2 > hotSpotLocationWidth + 175: self.log.screenshot("Hotspot is on center") return (abs(int(hotSpotLocationWidth - 125 - browserX / 2)), abs(int(hotSpotLocationWidth + 175 - browserX / 2)) ) # desno, levo except: pass return (0, 0) def view_tour(self, where, number): number = number * 2 for i in range(number): time.sleep(2) moveForX = int(int(self.tourImage().size["width"]) / 8) moveForY = int(int(self.tourImage().size["height"]) / 8) ac = ActionChains(self.driver) if not self._check_hotSpot_on_view(): ac.move_to_element(self.tourImage()) else: if i == 0: ac.move_to_element(self.tourImage()) hs_loc = self.where_to_move_edit_and_view() if where == "right": ac.move_by_offset(-1 * hs_loc[0], 0) elif where == "left": ac.move_by_offset(hs_loc[1], 0) else: break ac.click_and_hold() if where == "right": ac.move_by_offset(moveForX * -1, 0) elif where == "left": ac.move_by_offset(moveForX, 0) elif where == "up": ac.move_by_offset(0, moveForY * -1) elif where == "down": ac.move_by_offset(0, moveForY) ac.release() try: ac.perform() except: pass time.sleep(2) def is_hs_on_center(self): try: for hotSpot in get_hotSpots(self.log, self.driver): hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size centerOfBrowser = self.driver.find_element_by_tag_name( "body").size["width"] / 2 self.log.info( "Check if hotspot with x location={} is on center={}". format(hotSpotLocationWidth, centerOfBrowser)) if abs(self.tourImage().size["width"] / 2 - hotSpotLocationWidth) <= 55: return True except: pass return False def _check_hotSpot_on_view(self): """ Check if hotSpot is in center of view. And it shows to scene title=goingToScene. If hotSpot is not found or hotSpot is not in center exception is raised. :param goingToScene: Scene title that hotSpot should point :type goingToScene: str """ self.log.info("Execute method _check_hotSpot_on_view") for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size browserX = self.tourImage().size["width"] self.log.info( "Check if hotspot with x location={} is on view={}".format( hotSpotLocationWidth, browserX)) if hotSpotLocationWidth >= 0 and hotSpotLocationWidth <= browserX: self.log.screenshot("Hotspot is on view") return True except: pass return False def move(self, where, number, useArrows, view): if useArrows: for i in range(number): if where == "right": self.btnRighRotate().click() elif where == "left": self.btnLeftRotate().click() elif where == "up": self.btnDownRotate().click() elif where == "down": self.btnLeftRotate().click() else: for i in range(number): time.sleep(2) moveForX = int(int(self.tourImage().size["width"]) / 8) moveForY = int(int(self.tourImage().size["height"]) / 8) try: self.get_hotspot_from_center() except: ac = ActionChains(self.driver) ac.move_to_element(self.tourImage()) if where == "right": ac.move_by_offset(moveForX, 0) elif where == "left": ac.move_by_offset(-moveForX, 0) elif where == "up": ac.move_by_offset(0, moveForY) elif where == "down": ac.move_by_offset(0, -moveForY) ac.click_and_hold() if where == "right": ac.move_by_offset(moveForX * -1, 0) elif where == "left": ac.move_by_offset(moveForX, 0) elif where == "up": ac.move_by_offset(0, moveForY * -1) elif where == "down": ac.move_by_offset(0, moveForY) ac.release() ac.perform() time.sleep(2) def get_number_rotate(self, pixels, width): oneMove = int(width / 36) # 36 is number of clicking on rotate for 360 if width / 2 > pixels: # move left moveForPixels = width / 2 - pixels numberRotate = int(moveForPixels / oneMove) return False, numberRotate else: # move right moveForPixels = pixels - width / 2 numberRotate = int(moveForPixels / oneMove) return True, numberRotate def rotate_scene(self, pixels, width, useArrows=True, viewTour=False, up=False, down=False): """ Width is full picture size. Pixels are inside of full width. This method will rotate scene so that pixels are on center of scene. :param pixels: Move scene to center of this location :type pixels: int :param width: Full width of scene :type width: int :return: Info about rotate number and direction. If bool True direction is right, otherwise left. Rotate number is number of times to rotate. :rtype: bool, int """ self.log.info( "Execute method rotate_scene with parameters pixels={}, width={}". format(pixels, width)) scroll_element_to_center(self.driver, self.log, self.tourImage()) oneMove = int(width / 36) #36 is number of clicking on rotate for 360 if width / 2 > pixels: #move left moveForPixels = width / 2 - pixels numberRotate = int(moveForPixels / oneMove) rotate = ["left:{}".format(numberRotate)] if up != 0: rotate.append("up:{}".format(up)) elif down: rotate.append("down:{}".format(down)) self.rotate2(rotate, useArrows, viewTour) return False, numberRotate else: #move right moveForPixels = pixels - width / 2 numberRotate = int(moveForPixels / oneMove) rotate = ["right:{}".format(numberRotate)] if up: rotate.append("up:1") elif down: rotate.append("down:3") self.rotate2(rotate, useArrows, viewTour) return True, numberRotate def save_hotSpot(self): """ After hotSpot is added to location click on save button. """ self.log.info("Execute method save_hotSpot") self.btnSaveHotSpot().click() time.sleep(2) def publish(self): """ Execute publish button """ self.log.info("Execute method publish") self.btnPublish().click() time.sleep(2) def change_current_scene(self, title): """ Change current scene by clicking on pictures with title. :param title: Scene to change to :type title: str """ self.log.info( "Execute method change_current_scene with title={}".format(title)) self.wait_scene_load() self.driver.find_element_by_xpath( "//h5[contains(text(),'{}')]".format(title)).click() self.wait_scene_load() scroll_element_to_center(self.driver, self.log, self.tourImage()) self.log.screenshot("Current scene changed to {}".format(title)) def wait_scene_load(self): """ When scene is chosen wait for it to load """ self.driver.set_page_load_timeout(30) time.sleep(3) wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_class_name( "pnlm-render-container").find_element_by_tag_name("canvas")), timeout=60) wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "div[class='pnlm-load-box']")), timeout=30) wait_until( lambda: "inline" not in self.driver.find_element_by_css_selector( "div[class='pnlm-load-box']").get_attribute('style'), timeout=60) def pan_to_view(self): """ Click on button panToView """ self.log.info("Execute method pan_to_view") self.driver.execute_script("arguments[0].click();", self.btnPanToView()) #self.click_on_element(self.btnPanToView) time.sleep(3) def stop_rotate(self): self.rotate(False, 1, True) self.pan_to_view() def insert_hotSpots(self, scenes): """ Insert hotSpots that are defined in scenes :param scenes: Data for scenes :type scenes: list[Scenes] """ self.log.info( "Execute method insert_hotSpots with parameter scenes={}".format( "".join(scenes.__repr__()))) for scene in scenes: self.change_current_scene(scene.title) self.stop_rotate() for hotSpot in scene.hotSpots: self.rotate_scene(hotSpot.location, scene.width, useArrows=False, up=hotSpot.up, down=hotSpot.down) self.add_button_to_center() self._set_hotSpot_goingTo(hotSpot.goingToScene) self.save_hotSpot() self.pan_to_view() def rotate_scene_cursor(self, location, width): for i in range(7): time.sleep(10) self.half_rotate() def half_rotate(self): ac = ActionChains(self.driver) ac.move_to_element(self.tourImage()) ac.click_and_hold() ac.move_by_offset(self.tourImage().size["width"] / 2, 0) ac.release() ac.perform() def full_rotate(self): ac = ActionChains(self.driver) ac.move_to_element(self.tourImage()) ac.move_by_offset(-1 * self.tourImage().size["width"] / 2, 0) ac.click_and_hold() ac.move_by_offset(self.tourImage().size["width"], 0) ac.release() ac.perform() def delete_hotSpot(self, scene, hotSpotLocation, center=True): """ Delete hotSpot from scene where location is hotSpotLocation. :param scene: Scene to delete hotSpot from :type scene: Scene :param hotSpotLocation: Location in pixels :type hotSpotLocation: int """ self.log.info("Execute method delete_hotSpot with parameter scene={}, " "hotSpotLocation={}".format(scene, hotSpotLocation)) self.change_current_scene(scene.title) self.stop_rotate() self.rotate_scene(hotSpotLocation, scene.width, False) self.delete_hotSpotOrInfo_center(True) def _set_hotSpot_goingTo(self, title): """ After hotSpot is moved to scene, chose going to scene. :param title: Title of scene for hotSpot to show :type title: str """ self.log.info( "Execute method _set_hotSpot_goingTo with parameter={}".format( title)) options = self.driver.find_element_by_xpath( "//select[@id='select-hotSpots']") goingTo = self.driver.find_element_by_xpath( "//select[@id='select-hotSpots']/option[text()='{}']".format( title)) scroll_element_to_center(self.driver, self.log, options) options.click() time.sleep(2) goingTo.click() time.sleep(2) def open_menu_hotSpotOrInfo_center(self): """ Open menu of button in center of tour """ time.sleep(5) self.get_hotspot_from_center().click() wait_until(lambda: check_if_elem_exist(self.btnDeleteHotSpot), timeout=10) self.log.screenshot("Clicked on hotspot") def open_menu_hotSpotOrInfo_on_view(self): """ Open menu of button in center of tour """ time.sleep(5) hotSpotFound = None for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size tourSceneSize = self.tourImage().size["width"] self.log.info( "Check if hotspot with x location={} is on view={}".format( hotSpotLocationWidth, tourSceneSize)) limit = 50 if hotSpotLocationWidth >= 0 and hotSpotLocationWidth <= tourSceneSize: self.log.screenshot("Hotspot is on view") hotSpotFound = hotSpot hotSpot.click() except Exception as ex: self.log.info(str(ex)) if hotSpotFound is None: raise Exception("HotSpot is not in center") wait_until(lambda: check_if_elem_exist(self.btnDeleteHotSpot), timeout=10) self.log.screenshot("Clicked on hotspot") def edit_hotSpot_center(self): """" Edit hotSpot """ self.log.info("Execute method edit_hotSpot_center") self.open_menu_hotSpotOrInfo_center() self.btnEditHotSpot().click() time.sleep(1) self.log.info("Edit hotspot clicked") action_chains = ActionChains(self.driver) scroll_element_to_center(self.driver, self.log, self.get_hotspot_from_center()) move_mouse_to_middle_of_browser(self.log, self.driver) action_chains.drag_and_drop_by_offset(self.get_hotspot_from_center(), 5, 0).perform() time.sleep(1) self.log.screenshot("Edit for hotSpot is opened") def edit_hotSpot_goingTo(self, title): """ After hotSpot is moved to scene, chose going to scene. :param title: Title of scene for hotSpot to show :type title: str """ self.log.info( "Execute method _set_hotSpot_goingTo with parameter={}".format( title)) self.driver.execute_script( "arguments[0].click();", self.driver.find_element_by_xpath( "//select[@id='edit-select-hotSpots']/option[text()='{}']". format(title))) # self.driver.find_element_by_xpath("//select[@id='edit-select-hotSpots']/option[text()='{}']" # .format(title)).click() def save_edited_hotSpot(self): """ After hotSpot is added to location click on save button. """ self.log.info("Execute method save_hotSpot") self.btnSaveEditedHotSpot().click() time.sleep(2) def goTo_hotSpot_center(self): """ Click on goTo in hotspot menu """ self.open_menu_hotSpotOrInfo_center() self.log.info("Clicked on hotspot") self.btnGoToHotSpot().click() scroll_element_to_center(self.driver, self.log, self.tourImage()) time.sleep(1) self.log.screenshot("GoTo hotspot clicked") self.wait_scene_load() self.log.screenshot("Moved to another scene") def choose_arrow(self, number): """ Choose arrow type when adding or editing hotSpot. :param number: Number form 1 to 9 :type number: int """ self.log.info( "Execute method choose_arrow with paramter number={}".format( number)) self.imgArrowType(number).click() time.sleep(1) def add_info_button_center(self, title, name, url): """ Add info button on center of tour and puts information. """ self.log.info("Execute method add_info_button_center with parameters " "title={}, name={}, url={}".format(title, name, url)) self.stop_rotate() self.add_button_to_center(hotSpot=False) self._add_info_data(title, name, url) self.log.info("Method add_info_button_center finished") def edit_info_button_center(self, title, name, url): """ Edit info button on center of tour and puts information. """ self.log.info("Execute method edit_info_button_center with parameters " "title={}, name={}, url={}".format(title, name, url)) action_chains = ActionChains(self.driver) time.sleep(2) self.open_menu_hotSpotOrInfo_center() time.sleep(2) action_chains.click(self.divHotSpotMenu().find_element_by_css_selector( "a[onclick*='onInfoEdit']")).perform() time.sleep(2) scroll_element_to_center(self.driver, self.log, self.get_hotspot_from_center()) move_mouse_to_middle_of_browser(self.log, self.driver) ActionChains(self.driver).drag_and_drop_by_offset( self.get_hotspot_from_center(), 5, 0).perform() time.sleep(1) self._add_info_data(title, name, url, "update") def delete_hotSpotOrInfo_center(self, center=True): """ Delete hotSpot or info, depending what is on center of tour """ self.log.info("Execute method delete_hotSpotOrInfo_center") time.sleep(1) if center: self.open_menu_hotSpotOrInfo_center() else: self.open_menu_hotSpotOrInfo_on_view() self.log.screenshot("Click on delete hotspot") self.btnDeleteHotSpot().click() time.sleep(1) try: alert = self.driver.switch_to.alert except Exception as es: self.driver.log.info("First try to delete button not succeeded") self.btnDeleteHotSpot() alert = self.driver.switch_to.alert alert.accept() try: self.get_hotspot_from_center() raise Exception("Hotspot not deleted") except Exception as ex: pass self.log.screenshot("Hotspot is deleted")
class DriverData: mobile = False mobileHeight = None mobileWidth = None driverName = "" fullHeight = None height = None width = None mobileToTest = None orientation = None tabHeight = None #for chrome def __init__(self, driver="Firefox", mobileToTest=None, orientation="Portrait"): """ Creates driver and hold arguments for mobileToTest and orientation. If mobileToTest is not forwarded driver will test like on computer. Another way to forward this parameters are from command line with arguments --browser, --config, --mobile, --orientation. Example of command: python Test.py --browser=Firefox --config=Case1 --mobile="galaxyS9/S9+" --orientation=Landscape :param driver: Driver name :type driver: str :param mobileToTest: Key value from MobileTesting.json file from Configuration folder :type mobileToTest: str :param orientation: Used only if mobileToTest is forwarded. Possible values: Portrait and Landscape :type orientation: str """ if platform.system() in "Windows": from ctypes import windll if windll.user32.BlockInput(True) == 0: raise Exception("Not running script as admin") if is_forwarded("browser") is not None: driver = is_forwarded("browser") DriverData.driverName = driver if is_forwarded("mobile") is not None: mobileToTest = is_forwarded("mobile") if mobileToTest is not None: DriverData.mobile = True if is_forwarded("orientation") is not None: orientation = is_forwarded("orientation") DriverData.mobileToTest = mobileToTest DriverData.orientation = orientation self.driver = self._create_driver(driver, mobileToTest, orientation) self.log = Log(self.driver) if mobileToTest is not None: self.log.info( "Driver to create is={}, on mobile={} and orientation={}". format(driver, mobileToTest, orientation)) else: self.log.info( "Driver to create is={}. Testing on desktop computer".format( driver)) def get_driver(self): """ Get driver instance :return: Driver instance (WebDriver) """ return self.driver def _create_driver(self, driverString, mobileToTest, orientation): """ Create driver instance :param driverString: Browser name :type driverString: str user_pref("devtools.responsive.userAgent", "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/12.0 Mobile/15A372 Safari/604.1"); :return: driver :rtype: WebDriver devtools.responsive.userAgent """ if driverString == "Firefox": driver = self.create_firefox_driver(mobileToTest, orientation) elif driverString == "Chrome": driver = self.create_chrome_driver(mobileToTest, orientation) elif driverString == "Safari": driver = self.create_safari_driver(mobileToTest, orientation) else: raise Exception( "Supported drivers are Firefox and Chrome. You forwarded {}". format(driverString)) return driver def create_firefox_driver(self, mobileToTest, orientation): """ Create firefox driver :param mobileToTest: Mobile to test from file Configuration/MobileTesting.json (example: galaxyS9/S9+) :type mobileToTest: str :param orientation: Can be Landscape or Portrait :type orientation: str :return: WebDriver """ if mobileToTest is not None: size = get_mobile_size(mobileToTest, orientation) driver = webdriver.Firefox() driver.set_window_size(size['width'], size['height']) innerWidth = driver.execute_script("return window.innerWidth") innerHeight = driver.execute_script("return window.innerHeight") browserWidth = size['width'] + (size['width'] - innerWidth) browserHeight = size['height'] + (size['height'] - innerHeight) driver.close() driver = webdriver.Firefox() driver.set_window_size(browserWidth, browserHeight) else: driver = webdriver.Firefox() driver.maximize_window() # self.get_set_browser_tab_section_height(driver) set_height_width(driver) return driver def create_chrome_driver(self, mobileToTest, orientation): """ Create Chrome driver :param mobileToTest: Mobile to test from file Configuration/MobileTesting.json (example: galaxyS9/S9+) :type mobileToTest: str :param orientation: Can be Landscape or Portrait :type orientation: str :return: WebDriver """ if mobileToTest is not None: driver = self.create_chrome_driver_mobile(mobileToTest, orientation) else: driver = self.create_chrome_driver_desktop() return driver def create_safari_driver(self, mobileToTest, orientation): """ Create safari driver :param mobileToTest: Mobile to test from file Configuration/MobileTesting.json (example: galaxyS9/S9+) :type mobileToTest: str :param orientation: Can be Landscape or Portrait :type orientation: str :return: WebDriver """ driver = webdriver.Safari() if mobileToTest is not None: size = get_mobile_size(mobileToTest, orientation) DriverData.mobileHeight = size["height"] DriverData.mobileWidth = size["width"] driver.set_window_size(size["width"], size["height"]) driver.set_window_position(0, 0) else: driver.maximize_window() return driver def close(self): """ Close driver and all handles (all tabs...) """ close_driver(self.driver) def set_browser_tab_section_height_mobile(self): """ Set DriverData.tabHeight, height of opened browser """ if self.mobile and self.driverName == "Chrome": chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--disable-infobars") driver = webdriver.Chrome(chrome_options=chrome_options) driver.maximize_window() time.sleep(1) self.get_set_browser_tab_section_height(driver) driver.close() # elif self.mobile and self.driverName == "Firefox": # driver = webdriver.Firefox() # driver.maximize_window() # time.sleep(1) # DriverData.tabHeight = self.get_set_browser_tab_section_height(driver) # driver.close() def get_set_browser_tab_section_height(self, driver): """ Return and set DriverData.tabHeight of browser :param driver: Created driver :type driver: WebDriver :return tabHeight """ tabHeight = driver.get_window_size()["height"] - int( driver.find_element_by_tag_name("html").get_attribute( "clientHeight")) DriverData.tabHeight = tabHeight return tabHeight def create_chrome_driver_mobile(self, mobileToTest, orientation): """ Create chrome driver for mobile :param mobileToTest: :param orientation: :return: """ self.set_browser_tab_section_height_mobile() chrome_options = webdriver.ChromeOptions() mobileSize = get_mobile_size(mobileToTest, orientation) DriverData.mobileHeight = mobileSize["height"] DriverData.mobileWidth = mobileSize["width"] deviceMetrics = {"deviceMetrics": mobileSize} chrome_options.add_experimental_option("mobileEmulation", deviceMetrics) chrome_options.add_argument("--disable-infobars") driver = webdriver.Chrome(chrome_options=chrome_options) driver.maximize_window() set_height_width(driver) return driver def create_chrome_driver_desktop(self): """ Create chrome in desktop mode :return: WebDriver """ chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--disable-infobars") driver = webdriver.Chrome(chrome_options=chrome_options) driver.maximize_window() set_height_width(driver) self.get_set_browser_tab_section_height(driver) return driver
class LogIn: def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpUsername(self): return self.driver.find_element_by_id("user_login") def inpPassword(self): return self.driver.find_element_by_id("user_pass") def btnLogIn(self): return self.driver.find_element_by_id("wp-submit") def cbxSocialID(self): return self.driver.find_element_by_class_name( "heateor_ss_social_login_optin") def btnLoginWithFacebook(self): return self.driver.find_element_by_css_selector( "i[title='Login with Facebook']") def inpFacebookEmail(self): return self.driver.find_element_by_css_selector("input[id='email']") def inpFacebookPass(self): return self.driver.find_element_by_css_selector("input[id='pass']") def btnLogInToFacebook(self): return self.driver.find_element_by_css_selector( "button[id='loginbutton']") def log_in(self, username, password): """ Insert log in parameters and click on log in :param username: :param password: """ self.log.info("Execute method log_in with parameters: {}, {}".format( username, password)) wait_until(lambda: check_if_elem_exist(self.inpUsername), timeout=20) wait_until(lambda: self.inpUsername().is_displayed, timeout=20) time.sleep(3) self.inpUsername().send_keys(username) self.inpPassword().send_keys(password) self.log.info("Click on log in button") self.btnLogIn().click() time.sleep(2) def log_in_social_media(self, email, password): """ Log in with facebook account :param email: Email :param password: Password """ self.log.info( "Execute method log_in_social_media with parameters email={}, password={}" .format(email, password)) self.cbxSocialID().click() time.sleep(1) self.btnLoginWithFacebook().click() wait_until(lambda: len(self.driver.window_handles) == 2, timeout=10) self.driver.switch_to.window(self.driver.window_handles[-1]) wait_until(lambda: check_if_elem_exist(self.inpFacebookEmail), timeout=30) self.log.info("Facebook login page opened") send_text(self.inpFacebookEmail(), email, mode="update") send_text(self.inpFacebookPass(), password, mode="update") self.btnLogInToFacebook().click() time.sleep(10) self.log.screenshot("Should be logged on facebook")
class UploadScenesTour(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnUpload(self): return self.driver.find_element_by_css_selector( "div[class='qq-upload-button-selector qq-upload-button']") def get_number_uploaded_scenes(self): """ Get number of uploaded scenes :return: Number of uploaded scenes :rtype: int """ self.log.info("Execute method get_number_uploaded_scenes") scenes = self.driver.find_elements_by_css_selector( "div[class='scence-image col-lg-12 col-md-12 col-xs-12 col-sm-12']" ) numberOfScenes = len(scenes) self.log.info("Number of {} scenes".format(numberOfScenes)) return numberOfScenes def upload_scenes(self, scenes, timeout=300): """ Upload scenes and wait maximum of timeout for uploading. :param scenes: List of scenes :type scenes: list[Scene] :param timeout: Maximum time to wait for upload :type timeout: int """ beforeUpload = self.get_number_uploaded_scenes() self.log.info( "Execute method upload_scenes with parameters scenes={}, timeout={}" .format(scenes, timeout)) if platform.system() in "Windows": self.upload_scenes_windows(scenes) else: self.upload_scenes_mac(scenes) self.wait_scenes_uploaded(timeout) self.check_number_of_uploaded_scenes(beforeUpload, len(scenes)) self.log.screenshot("Scenes are uploaded") def upload_scenes_mac(self, scenes): """ Upload scenes for mac operating system. Forwarded scenes number and number of scenes path folder in Images folder must be the same. :param scenes: List of scenes :type scenes: list[Scene] """ self.log.info( "Execute method upload_scenes with parameters imagesPath={}". format(scenes)) imgs = get_images_path(scenes[0].folder) self.log.info("Scenes path is: {}".format(imgs)) wait_page_load(self.driver) self.btnUpload().click() wait_page_load(self.driver) pyautogui.keyDown("win") pyautogui.keyDown("shift") pyautogui.typewrite("g") time.sleep(5) pyautogui.keyUp("win") pyautogui.keyUp("shift") self.log.screenshot("Button upload clicked", True) time.sleep(5) pyautogui.typewrite(imgs) time.sleep(10) pyautogui.press('enter') time.sleep(10) pyautogui.press('right') time.sleep(10) pyautogui.keyDown("shift") time.sleep(5) pyautogui.press('down') time.sleep(5) pyautogui.press('down') time.sleep(5) pyautogui.press('down') time.sleep(5) pyautogui.keyUp("shift") time.sleep(10) self.log.screenshot("All scenes should be marked. Press enter.", True) pyautogui.press('enter') def upload_scenes_windows(self, scenes): """ Upload scenes for windows operating system. Forwarded scenes number and number of scenes path folder in Images folder must be the same. :param scenes: List of scenes :type scenes: list[Scene] """ from pywinauto.application import Application self.log.info( "Execute method upload_scenes with parameters scenes={}".format( scenes)) imgs = get_images_path(scenes[0].folder) self.log.info("Scenes path is: {}".format(imgs)) scroll_element_to_center(self.driver, self.log, self.btnUpload()) self.btnUpload().click() time.sleep(10) dialog_name = "" if DriverData.driverName == "Firefox": dialog_name = "File Upload" elif DriverData.driverName == "Chrome": dialog_name = "Open" app = Application().connect(title=dialog_name) time.sleep(3) app.Dialog.ComboBoxEx.Edit.type_keys(imgs) self.log.screenshot("Entered path to images", True) time.sleep(10) app.dlg.Open.click() time.sleep(10) app.Dialog.ComboBoxEx.Edit.type_keys(get_pictures_string(scenes)) time.sleep(10) app.dlg.Open.click() self.log.screenshot("Entered all images", True) def wait_scenes_uploaded(self, timeout): """ Wait for scenes to be uploaded. :param timeout: Maximum timeout to wait for uploading scenes :type timeout: int """ self.log.info("Execute method wait_scenes_uploaded with parameters" " timeout={}".format(timeout)) wait_until( lambda: check_if_elem_exist(lambda: self.driver. find_element_by_css_selector( "h3[id='toplimit']")), timeout) def check_number_of_uploaded_scenes(self, numberBeforeUpload, numberToUpload): """ Checks if number of uploaded scenes before uploading new scenes are increased by numberToUpload. Raise exception if scenes number=numberToUpload is not uploaded. :param numberBeforeUpload: Number of uploaded scenes before upload :type numberBeforeUpload: int :param numberToUpload: Uploaded scenes :type numberToUpload: int """ self.log.info( "Execute method check_number_of_uploaded_scenes with parameters " "numberBeforeUpload={}, numberToUpload={}".format( numberBeforeUpload, numberToUpload)) wait_until( lambda: numberBeforeUpload + numberToUpload == self. get_number_uploaded_scenes(), 30, errorMessage="Number of files that should be loaded={} are not the " "same as actual uploaded scenes".format(numberToUpload))
from Lib.SgPano.HomePage import HomePage from Lib.SgPano.LogIn import LogIn from Lib.common.ConfigLoader import ConfigLoader from Lib.common.DriverData import DriverData from Lib.common.Log import Log cl = ConfigLoader() createDriver = DriverData() driver = createDriver.get_driver() log = Log(driver) url = "https://sgpano.com/" log.info("Go to {}".format(url)) driver.get(url) hp = HomePage(driver) hp.go_to_log_in() lp = LogIn(driver) lp.log_in(cl.get("usernameTrial"), cl.get("passwordTrial"))
class Resources: def __init__(self, driver): self.driver = driver self.log = Log(driver) def tblBooked(self): return self.driver.find_element_by_css_selector( "table[class='table table-striped bookly-appointments-list dataTable no-footer dtr-inline']" ) def btnNext(self): return self.driver.find_element_by_css_selector( "button[class='bookly-next-step bookly-js-next-step bookly-btn ladda-button']" ) def check_if_exist(self, listingName, bookDate): wait_until(lambda: check_if_elem_exist(self.tblBooked)) all_booked = self.tblBooked().find_element_by_tag_name( "tbody").find_elements_by_tag_name("tr") for booked in all_booked: sections = booked.find_elements_by_tag_name("td") if bookDate in sections[0].text and listingName in sections[1].text: self.log.screenshot("Exists") return True self.log.screenshot("Does not exist!!!") return False def book(self, serviceName, selectionName): selectService = self.driver.find_element_by_css_selector("div[class='bookly-js-chain-item bookly-table bookly-box']")\ .find_element_by_css_selector("select[class='bookly-select-mobile bookly-js-select-service']") for service in selectService.find_elements_by_tag_name("option"): if serviceName in service.text: service.click() break time.sleep(2) selectSelection = self.driver.find_element_by_css_selector("div[class='bookly-js-chain-item bookly-table bookly-box']")\ .find_element_by_css_selector("select[class='bookly-select-mobile bookly-js-select-employee']") for selection in selectSelection.find_elements_by_tag_name("option"): if selectionName in selection.text: selection.click() break self.log.screenshot("Selected booking for {} and {}".format( serviceName, selectionName)) def booking_steps(self): if DriverData.mobile: self.driver.find_element_by_css_selector( "button[class='bookly-right bookly-mobile-next-step bookly-js-mobile-next-step bookly-btn bookly-none ladda-button']" ).click() else: self.btnNext().click() wait_until(lambda: check_if_elem_exist(lambda: self.driver. find_element_by_css_selector( "div[class='bookly-box']"))) wait_until(lambda: "Below you can find a list of available time slots" in self.driver.find_element_by_css_selector( "div[class='bookly-box']").text) self.log.screenshot("Opened 'Time'") if not DriverData.mobile: self.driver.find_element_by_css_selector("div[class='bookly-column bookly-js-first-column']")\ .find_element_by_css_selector("button[class='bookly-hour']").click() else: self.driver.find_element_by_css_selector( "button[class='bookly-next-step bookly-js-next-step bookly-btn ladda-button']" ) #wait_until(lambda: "Details" in self.active_booking_step()) wait_until(lambda: self.active_booking_step("Details")) self.log.screenshot("'Details' opened") booking = self.driver.find_element_by_css_selector( "div[class='bookly-box']").find_elements_by_tag_name("b") bookDate = booking[3].text bookTime = booking[2].text bookedFor = bookDate + " " + bookTime self.driver.find_element_by_css_selector( "button[class='bookly-next-step bookly-js-next-step bookly-btn ladda-button']" ).click() #wait_until(lambda: "Done" in self.active_booking_step()) wait_until(lambda: self.active_booking_step("Done")) self.log.screenshot("Booking is done") self.log.info("booked for {}".format(bookedFor)) return bookedFor def active_booking_step(self, stepName): steps = self.driver.find_element_by_css_selector( "div[class='bookly-progress-tracker bookly-table']" ).find_elements_by_tag_name("div") for step in steps: if "active" in step.get_attribute("class"): if stepName in step.text: return True return False
class EditScenes: def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnDeleteOk(self): return self.driver.find_element_by_css_selector( "button[class='ajs-button ajs-ok']") def divScenes(self): return self.driver.find_elements_by_css_selector( "div[class='col-lg-4 col-md-4 col-xs-12 col-sm-12']") def tourImage(self): return self.driver.find_element_by_class_name("pnlm-dragfix") def get_number_of_scenes(self): """ Get number of scenes :return: Number of scenes :rtype: int """ self.log.info("Execute method get_number_of_scenes") allScenesNumber = len(self.divScenes()) self.log.info("All scenes number is={}".format(allScenesNumber)) return allScenesNumber def find_scene_by_name(self, name): """ Find scene by name. If there is multiple tours with same name, first tour will be returned. If tour not found exception will be raised. :param name: Tour name :type name: str :return: Tour :rtype: WebElement """ time.sleep(2) self.log.info( "Execute method find_scene_by_name with parameter name={}".format( name)) sceneFound = False allScenes = self.divScenes() for scene in allScenes: if scene.find_element_by_tag_name("h3").text == name: sceneFound = True return scene if not sceneFound: raise Exception("Scene {} not found".format(name)) def remove_tour_by_name(self, name): """ Remove scene with name. If there is multiple tours with same name, first tour will be removed. :param name: Name of tour :type name: str """ self.log.info( "Execute method remove_tour_by_name with parameter name={}".format( name)) scenesNumber = self.get_number_of_scenes() scene = self.find_scene_by_name(name) if scene: self.log.info("Click on delete button") time.sleep(3) scene.find_element_by_css_selector( "a[class='scene_remove']").find_element_by_tag_name( "i").click() wait_until(lambda: check_if_elem_exist(self.btnDeleteOk), timeout=30) try: self.btnDeleteOk().click() if not scenesNumber == 1: wait_until( lambda: self.get_number_of_scenes() + 1 == scenesNumber, 10) else: wait_until(lambda: check_if_elem_exist( BasicInformationTour(self.driver).inpTitle), timeout=30) except: self.btnDeleteOk().click() wait_until( lambda: self.get_number_of_scenes() + 1 == scenesNumber, 10) self.log.screenshot("Scene is deleted") def view_tour_by_name(self, name): """ Click on view for tour with name. :param name: Name of tour to view :type name: str """ self.log.info( "Execute method view_tour_by_name with parameter name={}".format( name)) scene = self.find_scene_by_name(name) if DriverData.DriverData.mobile: link = scene.find_element_by_css_selector( "a[title='View']").get_attribute("href") self.driver.get(link) else: tab_number_before = len(self.driver.window_handles) self.log.info( "Number of tabs currently open={}".format(tab_number_before)) if scene: scene.find_element_by_css_selector( "a[title='View']").find_element_by_tag_name("i").click() self.log.info("Check if view is opened in new tab") wait_until( lambda: len(self.driver.window_handles) == tab_number_before + 1, 30) self.log.info("View is opened in new tab") for handle in self.driver.window_handles: self.driver.switch_to.window(handle) try: wait_until( lambda: name in self.driver.title, timeout=10, errorMessage= "Wrong tour is opened= {}. Tour= {} should be opened". format(self.driver.title, name)) break except: pass self.driver.refresh() def edit_tour(self, name): """ Click on edit for tour with name=name. :param name: Name of tour to edit :type name: str """ self.log.info( "Execute method edit_tour with parameter name={}".format(name)) scene = self.find_scene_by_name(name) if scene: #scene.find_element_by_css_selector("a[title='Edit']").click() scene.find_elements_by_css_selector( "a[title='Edit']")[1].find_element_by_tag_name("i").click() time.sleep(2) self.log.info("Scene found and clicked on edit button")
class SignUp(CommonAction): def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnTrialPanotour(self): return self.driver.find_element_by_css_selector("a[href*='level=1']") def btnTrialPanotourMobile(self): return self.driver.find_element_by_class_name("pmpro_advanced_levels-compare_table_responsive").find_element_by_css_selector("a[href*='level=1']") def btnBasicPanotour(self): return self.driver.find_element_by_css_selector("a[href*='level=2']") def btnBasicPanotourMobile(self): return self.driver.find_element_by_class_name("pmpro_advanced_levels-compare_table_responsive").find_element_by_css_selector("a[href*='level=2']") def inpUsername(self): return self.driver.find_element_by_id("username") def inpPassword(self): return self.driver.find_element_by_id("password") def inpPasswordConfirm(self): return self.driver.find_element_by_id("password2") def inpMail(self): return self.driver.find_element_by_id("bemail") def inpMailConfirm(self): return self.driver.find_element_by_id("bconfirmemail") def cbxTermsAndConditions(self): return self.driver.find_element_by_id("tos") def btnSubmit(self): return self.driver.find_element_by_css_selector("input[value^='Submit and Confirm']") def btnPayPal(self): return self.driver.find_element_by_css_selector("input[value*='Check Out with PayPal']") def inpPayPalEmail(self): return self.driver.find_element_by_css_selector("input[id='email']") def inpPayPalPass(self): return self.driver.find_element_by_css_selector("input[id='password']") # def btnLogInPayPal(self): # return self.driver.find_element_by_css_selector("button[id='btnLogin']") # def btnContinuePayPal(self): # return self.driver.find_element_by_css_selector("button[track-submit='choose_FI_interstitial']") def btnPayNow(self): return self.driver.find_element_by_css_selector("input[value='Pay Now']") def is_opened_right_page(self, membership): """ Check whether right page is opened :param membership: Trial, Basic... :type membership: str """ wait_until(lambda: membership in self.driver.find_element_by_css_selector("div[class='pmpro_checkout-fields']").text, timeout=30, errorMessage="Not right page opened") self.log.info("Page for memebership {} is opened".format(membership)) def wait_paypal_opened(self, timeout): self.log.info("Execute method wait_paypal_opened()") wait_until(lambda: "PayPal" in self.driver.title, timeout=timeout) def open_trial_panotour(self): """ Click on button Select for membership Trial with 1 Panotour. """ self.log.info("Execute method open_trial_panotour") if not self.btnTrialPanotour().is_displayed(): self.btnTrialPanotourMobile().click() else: self.btnTrialPanotour().click() self.is_opened_right_page("Trial") def open_basic_panotour(self): """ Click on button Select for membership Trial with 1 Panotour. """ self.log.info("Execute method open_basic_panotour") wait_until(lambda: check_if_elem_exist(self.btnBasicPanotour), timeout=20) if not self.btnBasicPanotour().is_displayed(): self.btnBasicPanotourMobile().click() else: self.btnBasicPanotour().click() self.is_opened_right_page("Basic") def _input_signup_info(self, username, password, mail): """ Put sign up information on site :param username: :param password: :param mail: """ self.inpUsername().send_keys(username) self.inpPassword().send_keys(password) self.inpPasswordConfirm().send_keys(password) self.inpMail().send_keys(mail) self.inpMailConfirm().send_keys(mail) self.cbxTermsAndConditions().click() self.log.screenshot("Sign up info is added") def sign_up_trial(self, username, password, mail, timeout=30): """ Input credentials and sign up :param username: Username :param password: Password :param mail: Email :param timeout: Timeout to wait, after submit, for new page to open """ self.log.info("Execute method _input_signup_info with parameters username={}, password={}, " "mail={}, timeout={}".format(username, password, mail, timeout)) self._input_signup_info(username, password, mail) self.log.info("Click on submit") self.btnSubmit().click() wait_until(lambda: self.driver.find_element_by_css_selector("div[class='titlebar-title sh-table-cell']").find_element_by_tag_name("h2") .text == "Membership Confirmation", timeout=timeout, period=2, errorMessage="Problem with sign up. Check log screenshots") self.log.screenshot("Sign up is successful") def sign_up_paid(self, username, password, mail, payPalEmail, payPalPassword, timeout=40): """ Sign up for accounts that are paid :param username: Username :param password: Password :param mail: Mail :param payPalEmail: PayPal email :param payPalPassword: PayPal password :param timeout: Timeout to wait for new page to show """ self.log.info("Execute method sign_up_paid with parameters username={}, password={}, " "mail={}, payPalEmail={}, payPalPassword={}, timeout={}".format(username, password, mail, payPalEmail, payPalPassword, timeout)) self._input_signup_info(username, password, mail) self.btnPayPal().click() self.pay_pal(payPalEmail, payPalPassword, timeout)
from Lib.SgPano.CreateEditTourConnectScenes import ConnectScenesTour from Lib.SgPano.CreateEditTourUploadScenes import UploadScenesTour from Lib.SgPano.CreateEditTourUploadedScenes import UploadedScenesTour from Lib.SgPano.Dashboard import Dashboard from Lib.SgPano.EditScenes import EditScenes from Lib.SgPano.HomePage import HomePage from Lib.SgPano.LogIn import LogIn from Lib.common.ConfigLoader import ConfigLoader from Lib.common.DriverData import DriverData from Lib.common.Log import Log from Lib.common.ScenesGetData import parse_to_scenes cl = ConfigLoader() createDriver = DriverData() driver = createDriver.get_driver() log = Log(createDriver) driver.get("https://sgpano.com/") hp = HomePage(driver) hp.go_to_log_in() lp = LogIn(driver) lp.log_in(cl.get("usernameTrial"), cl.get("passwordTrial")) db = Dashboard(driver) db.view_edit_tour() es = EditScenes(driver) es.edit_tour(cl.get("tourName"))
class AddNewDownloads: def __init__(self, driver): self.driver = driver self.log = Log(driver) def inpName(self): return self.driver.find_element_by_css_selector( "input[name='post_title']") def inpModelURL(self): return self.driver.find_element_by_id("mp_model_url") def divDownloadCategory(self): return self.driver.find_element_by_id("download_categorydiv") def divDownloadTags(self): return self.driver.find_element_by_id("tagsdiv-download_tag") def btnText(self): return self.driver.find_element_by_id("content-html") def txtDescription(self): return self.driver.find_element_by_css_selector( "textarea[class='wp-editor-area']") def inpTag(self): return self.driver.find_element_by_id("new-tag-download_tag") def btnAddTag(self): return self.driver.find_element_by_class_name("tagadd") def inpEnableVariablePricing(self): return self.driver.find_element_by_id("edd_variable_pricing") def txtExcerpt(self): return self.driver.find_element_by_id("excerpt") def selAuthor(self): return self.driver.find_element_by_id("post_author_override") def inpSaveDraft(self): return self.driver.find_element_by_id("save-post") def aDownloadImage(self): return self.driver.find_element_by_css_selector( "a[href*='media-upload']") def aUploadImage(self): return self.driver.find_element_by_xpath( "//a[contains(text(),'{}')]".format("Upload Files")) def btnSelectFiles(self): return self.driver.find_element_by_id("__wp-uploader-id-1") def btnSetDownloadImage(self): return self.driver.find_element_by_css_selector( "button[class='button media-button button-primary button-large media-button-select']" ) def change_to_text(self): self.btnText().click() def set_name(self, name): send_text(self.inpName(), name) def set_advertisement_status(self, status): advertisement = self.driver.find_element_by_xpath( "//p[contains(text(), 'Advertisement Status')]/following-sibling::p" ) advertisement.find_element_by_css_selector( "input[value='{}']".format(status)).click() def set_advertisement_type(self, type): advertisement = self.driver.find_element_by_xpath( "//*[contains(text(), 'Advertisement Type')]/following-sibling::p") advertisement.find_element_by_css_selector( "input[value='{}']".format(type)).click() def set_description(self, desc): send_text(self.txtDescription(), desc) #descriptionArea = self.driver.find_element_by_id("tinymce").find_element_by_tag_name("p") #self.driver.execute_script("arguments[0].textContent = arguments[1];", descriptionArea, desc) def set_model_url(self, url): send_text(self.inpModelURL(), url) def locate_download_category(self): scroll_element_to_viewpoint_top(self.log, self.driver, self.divDownloadCategory()) self.log.screenshot() def locate_download_tags(self): scroll_element_to_viewpoint_top(self.log, self.driver, self.divDownloadTags()) self.log.screenshot() def set_download_category(self, bedrooms, floorLevel, residential, tenor): """ :param bedrooms: Serial number on bedrooms :param floorLevel: :param residential: :param tenor: :return: """ bedroomsList = self.divDownloadCategory().find_element_by_id("download_category-58").\ find_element_by_tag_name("ul").find_elements_by_tag_name('li') bedroomElement = bedroomsList[bedrooms - 1].find_element_by_tag_name("input") self.driver.execute_script("arguments[0].click()", bedroomElement) #scroll_element_to_center(self.driver, self.log, bedroomElement) #bedroomElement.click() floorLevelList = self.divDownloadCategory().find_element_by_id("download_category-66").\ find_element_by_tag_name("ul").find_elements_by_tag_name('li') floorLevelElement = floorLevelList[floorLevel - 1].find_element_by_tag_name("input") self.driver.execute_script("arguments[0].click()", floorLevelElement) #scroll_element_to_center(self.driver, self.log, floorLevelElement) #floorLevelElement.click() residentialList = self.divDownloadCategory().find_element_by_id("download_category-72").\ find_element_by_tag_name("ul").find_elements_by_tag_name('li') residentialElement = residentialList[ residential - 1].find_element_by_tag_name("input") self.driver.execute_script("arguments[0].click()", residentialElement) #scroll_element_to_center(self.driver, self.log, residentialElement) #residentialElement.click() tenorList = self.divDownloadCategory().find_element_by_id("download_category-77").\ find_element_by_tag_name("ul").find_elements_by_tag_name('li') tenorElement = tenorList[tenor - 1].find_element_by_tag_name("input") self.driver.execute_script("arguments[0].click()", tenorElement) #scroll_element_to_center(self.driver, self.log, tenorElement) #tenorElement.click() def add_tag(self, tag): expandButton = self.driver.find_element_by_id( "tagsdiv-download_tag").find_element_by_tag_name("button") if "false" in expandButton.get_attribute("aria-expanded"): expandButton.click() send_text(self.inpTag(), tag) self.btnAddTag().click() def enable_variable_pricing(self): scroll_element_to_center(self.driver, self.log, self.inpEnableVariablePricing()) self.inpEnableVariablePricing().click() self.log.screenshot() def set_excerpt(self, text): send_text(self.txtExcerpt(), text) self.log.screenshot() def choose_author(self, user): # self.selAuthor().click() # time.sleep(1) sel = Select(self.selAuthor()) sel.select_by_visible_text(user) # self.selAuthor().find_element_by_xpath("/option[contains(text(),'{}')]".format(user)).click() time.sleep(1) self.log.screenshot() def save_draft(self): scroll_element_to_center(self.driver, self.log, self.inpSaveDraft()) time.sleep(1) self.log.screenshot() #self.inpSaveDraft().click() self.driver.execute_script("arguments[0].click();", self.inpSaveDraft()) def select_first_image(self): wait_until(lambda: len( self.driver.find_elements_by_css_selector( "div[class='attachment-preview js--select-attachment type-image subtype-gif landscape']" )) > 0) self.driver.find_elements_by_css_selector( "div[class='attachment-preview js--select-attachment type-image subtype-gif landscape']" )[0].click() def set_download_image(self, upload=False): self.log.info("Execute method set_download_image") found = False firstTry = True while (not found): self.aDownloadImage().click() self.log.screenshot("kliknuto") #self.aUploadImage().click() #self.btnSelectFiles().click() #upload_scenes_windows(self.driver, DriverData.driverName, self.log, r"C:\Users\radlo\PycharmProjects\FromGitTemasek\Images\temasekproperties", "Webpr") if firstTry: self.select_first_image() time.sleep(2) self.log.screenshot("selektovan prvi") wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "span[class='spinner']")), timeout=180) self.log.screenshot("Images are shown") self.btnSetDownloadImage().click() try: wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "img[class='attachment-post-thumbnail size-post-thumbnail']" )), timeout=600) print("Pronasao") found = True except Exception as ex: pass firstTry = False
class HomePage: def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnTemasekproperties(self): return self.driver.find_element_by_css_selector( "a[href='https://temasekproperties.com/wp-admin/']") def btnDownloads(self): return self.driver.find_element_by_css_selector( "a[href='edit.php?post_type=download']") def spnExpandMenu(self): return self.driver.find_element_by_css_selector( "span[class='c-hamburger c-hamburger--htx']") def go_to_downloads(self): self.btnTemasekproperties().click() wait_until( lambda: self.driver.find_element_by_tag_name("h1").text == "Dashboard", 20) self.btnDownloads().click() def go_to_user_profile(self): if DriverData.mobile: self.spnExpandMenu().click() startElem = self.driver.find_element_by_css_selector( "ul[class='sh-nav-mobile']").find_element_by_id( "menu-item-9049") else: startElem = self.driver.find_element_by_css_selector( "nav[id='header-navigation']").find_element_by_id( "menu-item-9049") startElem.find_element_by_tag_name("a").click() time.sleep(1) startElem.find_element_by_css_selector( "li[class*='menu-item-9129']").click() def go_to_listings(self): wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "nav[id='header-navigation']"))) if DriverData.mobile: self.spnExpandMenu().click() start_elem = self.driver.find_element_by_css_selector( "nav[class='sh-header-mobile-dropdown']") else: start_elem = self.driver.find_element_by_id("header-navigation") start_elem.find_elements_by_css_selector( "a[href='https://temasekproperties.com/listings/']")[0].click() def go_to_listings_nfe(self): wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "nav[id='header-navigation']"))) if DriverData.mobile: self.spnExpandMenu().click() start_elem = self.driver.find_element_by_css_selector( "nav[class='sh-header-mobile-dropdown']") else: start_elem = self.driver.find_element_by_id("header-navigation") start_elem.find_elements_by_css_selector( "a[href='https://temasekproperties.com/listings-nfe/']")[0].click( ) #https://temasekproperties.com/listings-nfe/ def go_to_resources_booked(self): if DriverData.mobile: self.spnExpandMenu().click() start_elem = self.driver.find_element_by_id( "header-navigation-mobile") else: start_elem = self.driver.find_element_by_id( "header-navigation") # for mobile: header-navigation-mobile start_elem.find_element_by_id("menu-item-9408").click() time.sleep(2) wait_until(lambda: "block" in self.driver.find_element_by_id( "header-navigation").find_element_by_id("menu-item-9408"). find_element_by_tag_name("ul").get_attribute("style")) self.driver.find_element_by_id("header-navigation").find_element_by_id( "menu-item-9434").click() time.sleep(3) wait_until( lambda: check_if_elem_exist(lambda: self.driver.find_element_by_id( "DataTables_Table_0_processing"))) wait_until(lambda: "none" in self.driver.find_element_by_id( "DataTables_Table_0_processing").get_attribute("style")) self.log.screenshot("resource booked opened") def go_to_resources_booking(self): if DriverData.mobile: self.spnExpandMenu().click() start_elem = self.driver.find_element_by_css_selector( "ul[class='sh-nav-mobile']") else: start_elem = self.driver.find_element_by_id( "header-navigation") # for mobile: header-navigation-mobile start_elem.find_element_by_id("menu-item-9408").click() time.sleep(2) wait_until( lambda: "block" in start_elem.find_element_by_id("menu-item-9408"). find_element_by_tag_name("ul").get_attribute("style")) start_elem.find_element_by_id("menu-item-9409").click() time.sleep(3) wait_until(lambda: check_if_elem_exist( lambda: self.driver.find_element_by_css_selector( "div[class='bookly-progress-tracker bookly-table']"))) # wait_until(lambda: "none" in self.driver.find_element_by_id("DataTables_Table_0_processing").get_attribute("style")) self.log.screenshot("resource booking opened")
def __init__(self, driver): self.driver = driver self.log = Log(driver)
class ViewTour: def __init__(self, driver): self.driver = driver self.log = Log(driver) def btnShowAllScenes(self): return self.driver.find_element_by_id("gallery") #return self.driver.find_element_by_css_selector("img[alt='gallef']") def paneGallery(self): return self.driver.find_element_by_css_selector( "div[id='gallerypane']") def tourImage(self): return self.driver.find_element_by_class_name("pnlm-dragfix") def get_current_scene_title(self): """ Return current scene title :return: Scene title :rtype: str """ self.log.info("Execute method get_current_scene_title") sceneTitle = self.driver.find_element_by_css_selector( "div[id='titleDiv']").text self.log.info("Current scene title is={}".format(sceneTitle)) return sceneTitle def open_scene(self, name): """ Change current scene to scene with name=name :param name: Name of scene to open :type name: str """ cst = ConnectScenesTour(self.driver) cst.wait_scene_load() self.log.info( "Execute method open_scene with parameter={}".format(name)) try: wait_until(lambda: not self.paneGallery().is_displayed, timeout=10) except Exception as ex: pass if not self.driver.find_element_by_css_selector( "div[id='gallerypane']").is_displayed(): self.log.info("Click on button show all scenes") #self.btnShowAllScenes().click() self.driver.execute_script("arguments[0].click();", self.btnShowAllScenes()) time.sleep(2) wait_until(lambda: self.paneGallery().is_displayed, timeout=30) self.log.screenshot("Gallery is displayed") self.driver.find_element_by_xpath( "//h5[contains(text(),'{}')]".format(name)).click() cst.wait_scene_load() cst.rotate(True, 1, True) cst.rotate(False, 1, True) #self.tourImage().click() self.btnShowAllScenes().click() def _check_hotSpot_in_center(self, goingToScene, view=False): """ Check if hotSpot is in center of view. And it shows to scene title=goingToScene. If hotSpot is not found or hotSpot is not in center exception is raised. :param goingToScene: Scene title that hotSpot should point :type goingToScene: str """ self.log.info( "Execute method _check_hotSpot_in_center with gointTo scene parameter={}" .format(goingToScene)) for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size centerOfBrowser = self.driver.find_element_by_tag_name( "body").size["width"] / 2 self.log.info( "Check if hotspot with x location={} is on center={}". format(hotSpotLocationWidth, centerOfBrowser)) limit = self.tourImage().size["width"] if hotSpotLocationWidth > 0 and hotSpotLocationWidth < centerOfBrowser * 2 and abs( abs(hotSpotLocationWidth + size["width"] / 2) - centerOfBrowser) < limit: #allowed error of 500 pixels self.log.screenshot("Hotspot is in center") return True except Exception as ex: pass raise Exception("Hotspot not found") def _check_hotSpot_on_view(self): """ Check if hotSpot is in center of view. And it shows to scene title=goingToScene. If hotSpot is not found or hotSpot is not in center exception is raised. :param goingToScene: Scene title that hotSpot should point :type goingToScene: str """ self.log.info("Execute method _check_hotSpot_on_view") for hotSpot in get_hotSpots(self.log, self.driver): try: hotSpotLocation = hotSpot.get_attribute("style") translate = hotSpotLocation.split("translate(")[1].split( "px")[0] hotSpotLocationWidth = int(translate.split(".")[0]) size = hotSpot.size browserX = self.driver.find_element_by_tag_name( "body").size["width"] self.log.info( "Check if hotspot with x location={} is on view={}".format( hotSpotLocationWidth, browserX)) if hotSpotLocationWidth >= 0 and hotSpotLocationWidth < self.tourImage( ).size["width"]: self.log.screenshot("Hotspot is on view") return True except Exception as ex: pass raise Exception("Hotspot not found") def check_arrows(self, scenes, view=False): """ Check hotSpots for given scenes for location and scene that it shows to :param scenes: List of scene :type scenes: list[Scene] """ self.log.info("Execute method check_arrows with parameter={}".format( "".join(scenes.__repr__()))) cst = ConnectScenesTour(self.driver) connect_scene = ConnectScenesTour(self.driver) for scene in scenes: time.sleep(1) self.open_scene(scene.title) if "Safari" in DriverData.driverName and view: for i in range(2): connect_scene.btnZoomOut().click() else: for i in range(5): connect_scene.btnZoomOut().click() for i, hotSpot in enumerate(scene.hotSpots): number_rotate = cst.get_number_rotate(hotSpot.location, scene.width) if number_rotate[0]: where = "right" else: where = "left" cst.rotate2(["{}:{}".format(where, number_rotate[1])], False, view) time.sleep(2) if view: self._check_hotSpot_on_view() else: self._check_hotSpot_in_center(hotSpot.goingToScene, view) time.sleep(2) if not number_rotate[0]: where2 = "right" else: where2 = "left" if i < len(scene.hotSpots) - 1: rotate = [] if not view: if hotSpot.up: rotate.append("down:1") if hotSpot.down: rotate.append("up:3") rotate.append("{}:{}".format(where2, number_rotate[1])) cst.rotate2(rotate, False, view)