def __checkGuide(self, methodName): """Checks the PDF for the guide corresponding to the method name has been opened :param methodName: Name of the method calling me (e.g. "openUserGuideCheck") :return: None """ log("## %s" % methodName) if methodName == "openGettingStartedGuideCheck": guideName = "Getting Started Guide" button = "gsgPdf.png" elif methodName == "openUserGuideCheck": guideName = "User Guide" button = "ugPdf.png" elif methodName == "openTechnicalGuideCheck": guideName = "Technical Guide" button = "tgPdf.png" else: log("checkGuide: Unknown method, exiting...", "error") return if not exists(button, 5): self.projectBrowser.testInfo.failed("%s: Could not find the %s." % (methodName, guideName)) else: log("- Found the Getting Started Guide PDF in the Help menu.") sikuliUtils.closeChromeTab() click("projectBrowserHelpBtn.png") log("All checks performed for %s" % methodName.strip("Check"))
def createSequenceCheck(self): """Checker function to verify a new sequence has been created""" log('## createSequenceCheck') if exists('flixPopupOK.png', 3): self.projectBrowser.testInfo.failed('createSequenceCheck: Got ' 'the \'Sequence already exists\' error message.') click('flixPopupOK.png') return 1 # if not exists('%sSequence.png' % self.projectBrowser.testInfo.sequence, 5): # self.projectBrowser.testInfo.failed('createSequenceCheck: Failed to find ' # 'the \'%s/%s\' sequence in the Project Browser.' % ( # self.projectBrowser.testInfo.show, self.projectBrowser.testInfo.sequence)) # else: # log('- %s sequence found in the Project Browser.' % self.projectBrowser.testInfo.sequence) # path = self.projectBrowser.testInfo.getEditorialDir() if pyUtils.waitForFile(self.projectBrowser.editorialDir, 'fle', 10) == 0: self.projectBrowser.testInfo.failed('createSequenceCheck: Could not find the fle folder ' 'under the seq.%s.story/flix/editorial directory.' % self.projectBrowser.testInfo.sequence) return 1 else: log('- FLE directory found for the new sequence.') log('All checks performed for createSequence.')
def addDialogue(self, dialogue="Adding dialogue to panel [panelIndex].", firstPanel=1, lastPanel=3): """Adds dialogue to all of the panels currently in the sequence :param dialogue: String to add to every panel as the dialogue :param firstPanel: Panel index of first panel to add dialogue to :param lastPanel: Panel index of last panel to add dialogue to :return: None """ log('##### addDialogue') panels = [] for i in range(firstPanel, lastPanel+1): panels.append(i) log("addDialogue: Panel indices to add dialogue to: %s" % panels, "debug") url = "127.0.0.1:35980/html/index.html#show=%s;seq=%s;branch=%s;edit=%s;panel=%s" % \ (self.testInfo.show, self.testInfo.sequence, self.testInfo.currentBranch, self.testInfo.getEditVersion(), panels[0]) sikuliUtils.newChromeTab(url, closeCurrent=True); wait(5) click("dialogueField.png"); wait(1) for panel in panels: # Paste the dialogue (paste better than type as it keeps special characters) dial = dialogue.replace("[panelIndex]", str(panel)) sikuli.paste(unicode(dial, "utf8")); wait(1) sikuli.type(sikuli.Key.ENTER, sikuli.KeyModifier.SHIFT); wait(1) self.editToolsCheck.addDialogueCheck(panels, dialogue)
def importAudioCheck(self, timeout): log('## importAudioCheck') if not exists('importAudioOK.png', timeout): self.importDrawing.testInfo.failed('importAudioCheck: No popup found after %s seconds.' % timeout) else: log('- Found popup after importing audio.') click('importAudioOK.png') sikuliUtils.saveVersion(self.importDrawing.testInfo, 'Imported audio.') # Check mp3 file is in the editorial directory checkUtils.newAudioFile(self.importDrawing.testInfo, methodName='importAudioCheck') # Check mp3 is in the shotEdit shotEdit = self.importDrawing.testInfo.getShotEdit() if shotEdit: mp3Found = pyUtils.findOccurences('.mp3', shotEdit) if mp3Found != 1: self.importDrawing.testInfo.failed('importAudioCheck: Expected 1 audio file in the shotEdit, ' 'found %s instead.' % mp3Found) else: log('- Found imported audio file in the current shotEdit.') self.importDrawing.testInfo.editAudio = 1 else: self.importDrawing.testInfo.failed('importAudioCheck: shotEdit not found, cannot check for audio.') log('All checks performed for importAudio.')
def importPanels2(self, ext, nPanels=10): """Imports nPanels panels without checking image in Flix :param ext: extension of the files to import :param nPanels: Number of panels to import, 10 by default :return: None """ log('##### importPanels2') if self.testInfo.OS == "mac": log("importPanels only supported on Windows right now. Using importDrawings instead...", "error") self.importDrawings(ext, nPanels) return availablePanels = self.__getAvailablePanels(ext) panelList = [] while len(panelList) < nPanels: rest = nPanels - len(panelList) if rest > len(availablePanels): for panel in availablePanels: panelList.append(panel) else: for panel in availablePanels[0:rest]: panelList.append(panel) # Got to do it in chunks of 10 panels for i in range(0, len(panelList), 10): chunk = panelList[i:i+10] click('importDrawingsButton.png') if not exists('importFileBrowserFilename.png', 20): log('importPanels2: Could not find importFileBrowserFilename after 20 seconds.', 'error') return click('importFileBrowserFilename.png'); wait(1) if i == 0: type(self.importPath.replace('/', '\\')); wait(1) type(sikuli.Key.ENTER); wait(1) for panel in chunk: type("\"" + panel + "\" ") type(sikuli.Key.ENTER) # wait(len(chunk)) # Wait until the 'processing' image for the first panel timeout = int((len(chunk) * 1.5)) if ext == 'mov': timeout = 0 for movie in chunk: timeout += pyUtils.readMovSettings(self.testInfo, movie)['timeout'] log('importPanels2: timeout set to %ssec.' % timeout, 'debug') wait(timeout) self.importDrawingCheck.importPanels2Check(ext, nPanels, panelList)
def __publishFromFlix(self, methodName, comment, checkMethod, windowName="fcp", importAAFs=False, createSgSeq=False): """Method that will select the specified editorial plugin, publish with a comment and call the relevant check method :param methodName: Name of the method calling me :param comment: Comment to add to the publish :param checkMethod: Method to call to check the publish results :param windowName: Name of the Explorer window Flix reveals after publishing :param importAAFs: Set to True to import AAFs after Avid publish (not relevant for other editorial publishes) :param createSgSeq: Set to True to create the Flix sequence in Shotgun (only relevant for Shotgun publish) :return: None """ log("##### toEditorial: %s" % methodName) if methodName == "toShotgun" and createSgSeq: sikuliUtils.createShotgunSequence(self.testInfo) if self.testInfo.flixVersion < '5.2': click(sikuliUtils.switchPlugin('editorial', '%s.png' % methodName)); wait(1) else: sikuliUtils.switchPlugin('editorial', '%s.png' % methodName); wait(1) click('publishComment.png'); wait(1) type(comment); wait(1) type(sikuli.Key.TAB); wait(.5) type(sikuli.Key.ENTER) # Assuming .5 sec/frame is enough to publish an edit to editorial # timeout = self.testInfo.getDurationFromShotEdit()/2 # Assuming 2 sec/panel for stills and 1.5 sec/frame for animated panels is enough to publish an edit stillPanels = len(self.testInfo.editPanels["p"]) + len(self.testInfo.editPanels["s"]) animPanels = self.testInfo.editPanels["a"] animFrames = 0 for panel in animPanels: animFrames += self.testInfo.getPanelDurationFromShotEdit(panel) if methodName == "toAvid": stillTimeout = 2 animFrameTimeout = 1.5 else: stillTimeout = 0.5 animFrameTimeout = 0.5 timeout = int((stillTimeout*stillPanels) + (animFrameTimeout*animFrames)) if timeout < 20: timeout = 20 checkMethod(timeout) if methodName in ["toSbp", "toPremiere"]: sikuliUtils.closeExplorerWindow("%s" % windowName) elif importAAFs: self.launch.openEditorialGUI(10) self.editorialProjectBrowser.selectEditorialProject() self.__importToAvid()
def logIn(self, timeout): log('##### logIn') click('logInScreen.png'); wait(.5) type(sikuli.Key.TAB); wait(.5) type(self.testInfo.user); wait(1) type(sikuli.Key.TAB); wait(.5) type('latte'); wait(1) type(sikuli.Key.ENTER) self.launchCheck.launchFlixCheck(timeout)
def createNewPanels(self, n=3): """Creates n new panels using the New Button panel in Flix :param n: Number of new panels to be created :return: None """ log('##### createNewPanels') for _ in range(0, n): click('newPanelBtn.png'); wait(2) self.editToolsCheck.createNewPanelsCheck(n)
def openHelpMenuCheck(self): """Checks whether the Help menu has been open in the Project Browser :return: None """ log('## openHelpMenuCheck') if not exists("contactSupportBtn.png", 5): self.projectBrowser.testInfo.failed("openHelpMenuCheck: Could not find the Contact Support button.") else: log("- Found the Contact Support button in the Help menu.") click("projectBrowserHelpBtn.png") log("All checks performed for openHelpMenu")
def duplicatePanel(self, panel="panel1.png"): """Duplicate a panel, given the name of its screenshot :param panel: Name of the Sikuli screenshot associated with the panel to be copy/pasted :return: None """ log('##### duplicatePanel') if not click(panel): log('duplicatePanel: Could not find %s on screen, exiting test.' % panel, 'error') return click('duplicateBtn.png'); wait(1) self.editToolsCheck.duplicatePanelCheck(panel)
def openInPhotoshop(self, panels, psMethod): """Opens one or multiple panels in Photoshop using Layer Comps ('layerComp') or Timeline ('timeline') panels -- List of panels to open in Photoshop psMethod -- Either open the panels in 'layerComp' or 'timeline' view in PS """ log('##### openInPhotoshop') click(panels[0]) if len(panels) != 1: for panel in panels[1:]: # click(panel, sikuli.KeyModifier.CTRL) sikuliUtils.ctrlClick(panel) if psMethod == 'layerComp': plugin = 'photoshopLayerComp.png' elif psMethod == 'timeline': plugin = 'photoshopTimeline.png' else: log('openInPhotoshop: %s psMethod is not supported in this test.' % psMethod) return if self.testInfo.flixVersion < '5.2': click(sikuliUtils.switchPlugin('editing', plugin)) else: sikuliUtils.switchPlugin('editing', plugin) wait(1) # type(sikuli.Key.ENTER, sikuli.KeyModifier.CTRL) sikuliUtils.ctrlType('', sikuli.KeyModifier.ENTER) # Need to find a way to make sure the panel is open in Photoshop psState = sikuliUtils.oneOrTheOther('psOpen.png', 'psOpening.png', 30) if psState == 0: wait(5) elif psState == 1: wait(30) elif psState == 2: self.testInfo.failed('openInPhotoshop: Photoshop is not open and not opening.') sikuliUtils.psEdit() sikuli.App.focus('Google Chrome') for panel in panels: toPs.openInPhotoshopCheck(self.testInfo, panel)
def exportQuickTime(self, timeout=100): log('##### exportQuickTime') if not self.testInfo.getShotEdit(): log("Cannot use an export plugin when no edit is saved for this sequence; exiting...", "error") return if os.path.isdir(self.fleMovDir): shutil.rmtree(self.fleMovDir) if self.testInfo.flixVersion < '5.2': click(sikuliUtils.switchPlugin('export', 'exportQuicktime.png')) else: sikuliUtils.switchPlugin('export', 'exportQuicktime.png') self.exportCheck.exportQuickTimeCheck(timeout) sikuliUtils.closeExplorerWindow('fleMov')
def popupCheck(testInfo, timeout, methodName="methodName"): # Wait for the OK popup attempts = 10 for attempt in range(0, attempts): currentTime = int(timeout * (attempt + 1) / attempts) if not sikuliUtils.clearPopup(timeout / attempts): # Maybe it's the fail popup if exists("flixPopupClose.png"): testInfo.failed("%s: plugin failed after %s seconds." % (methodName, currentTime)) click("flixPopupClose.png") return 0 elif attempt == attempts: testInfo.failed("%s: No successful popup after %s seconds." % (methodName, timeout)) testInfo.failed("%s: No error popup either, probably needs to increase the timeout value." % methodName) return 0 else: log("- Found successful popup after less than %s seconds." % currentTime) return 1
def importAudio(self, filename="newWorld.mp3", timeout=100): log('##### importAudio') self.testInfo.allAudio = pyUtils.countFiles(self.mp3Dir, '*.mp3') path = "%s/%s" % (self.audioAssetsDir, filename) if not os.path.exists(path): log('importAudio: the audio file specified does not exist, exiting.\naudio file: %s' % path, 'error') return click('importDrawingsButton.png') if not exists('importFileBrowserFilename.png', 10): log('importAudio: Could not find importFileBrowserFilename after 10 seconds.', 'error') click('importFileBrowserFilename.png') type(path.replace('/', '\\')); wait(1) type(sikuli.Key.ENTER); wait(1) self.importDrawingCheck.importAudioCheck(timeout)
def createEpisodeCheck(self): log('## createEpisodeCheck') if exists('flixPopupOK.png', 3): self.projectBrowser.testInfo.failed('createEpisodeCheck: Got the ' '\'Episode already exists\' error message.', True) click('flixPopupOK.png') if not exists('%sEpisode.png' % self.projectBrowser.testInfo.episode, 5): self.projectBrowser.testInfo.failed('createEpisodeCheck: Failed to find the \'%s/%s\' ' 'episode in the Project Browser.' % (self.projectBrowser.testInfo.show, self.projectBrowser.testInfo.episode)) else: log('- %s episode found in the Project Browser.' % self.projectBrowser.testInfo.episode) if not os.path.exists(self.projectBrowser.testInfo.getEpisodeDir()): self.projectBrowser.testInfo.failed('createEpisodeCheck: Could not find the episode directory on disk.') else: log('- Found the episode directory on disk.') log('All checks performed for createEpisode.')
def importPanels(self, filebase, ext, nPanels): """Imports all the panels contained in the provided path info - dictionary containing info on the show/sequence filebase -- Basename for the files to import (e.g. testJpeg) ext -- Extension of the files to import (e.g. jpeg) nPanels -- Number of panels to import """ log('##### importPanels') if self.testInfo.OS == "mac": log("importPanels only supported on Windows right now. Using importDrawings instead...", "error") self.importDrawings(ext, nPanels) return availablePanels = self.__getAvailablePanels(ext) panelList = [] for n in range(1, nPanels+1): panelList.append('%s%s.%s' % (filebase, str(n), ext)) log('panelList: %s' % panelList, 'debug') click('importDrawingsButton.png') if not exists('importFileBrowserFilename.png', 10): log('Could not find importFileBrowserFilename after 10 seconds.', 'error') click('importFileBrowserFilename.png') type(self.importPath.replace('/', '\\')); wait(1) type(sikuli.Key.ENTER); wait(1) for panel in panelList: type("\"" + panel + "\" ") type(sikuli.Key.ENTER) self.importDrawingCheck.importPanelsCheck(ext, nPanels, panelList)
def exportPanels(self, settings, deletePoses=False): log('##### exportPanels') if not self.testInfo.getShotEdit(): log("Cannot use an export plugin when no edit is saved for this sequence; exiting...", "error") return if self.testInfo.OS == "mac": log("exportPanels is only supported on Windows at the moment. Exiting...", "error") return if deletePoses: pyUtils.deleteLocalPoses(self.testInfo) if settings['format'] == 'jpeg': plugin = 'exportJpegs.png' outputPath = self.jpgOutputDir elif settings['format'] == 'psd': plugin = 'exportPsds.png' outputPath = self.psdOutputDir else: self.testInfo.failed('%s is not a valid format. Must be \'psd\' or \'jpeg\'.' % settings['format']) return if os.path.isdir(outputPath): shutil.rmtree(outputPath) os.makedirs(outputPath) if self.testInfo.flixVersion < '5.2': pluginLocation = sikuliUtils.switchPlugin('export', plugin) click(settings['panels'][0]) if len(settings['panels']) != 1: for panel in settings['panels'][1:]: sikuliUtils.ctrlClick(panel) if self.testInfo.flixVersion < '5.2': click(pluginLocation) else: sikuliUtils.switchPlugin('export', plugin) if not exists('exportFileBrowser.png', 10): self.testInfo.failed('Could not find the File Browser.') click('exportFileBrowserFolder.png') type(outputPath.replace('/', '\\')); wait(1) type(sikuli.Key.ENTER); wait(1) type(sikuli.Key.BACKSPACE) type(sikuli.Key.ENTER) self.exportCheck.exportPanelsCheck(settings) sikuliUtils.closeExplorerWindow('%ss' % settings['format'])
def publishToFlix2(self, comment="Publish to Flix", assetName="refsFromPremiere", toShotgun=False, branch="main", asStills=True): log('##### publishToFlix') branch = "main" log("publishToFlix: branch set to 'main' by default as other branches aren't supported yet") self.testInfo.allAudio = pyUtils.countFiles(self.mp3Dir, "*.mp3") self.launch.openEditorialGUI(20, True) self.editorialProjectBrowser.selectEditorialProject() click(sikuli.Pattern('toAvidToFlix.png').targetOffset(20, 0)); wait(1) type(sikuli.Key.TAB); wait(1) type(sikuli.Key.TAB); wait(1) type(sikuli.Key.TAB); wait(1) movPath = "%s/%s.mov" % (self.assetsDir, assetName) type(movPath) type(sikuli.Key.TAB); wait(1) edlPathBase = "%s/%s" % (self.assetsDir, assetName) edlPathAvid = "%s.txt" % edlPathBase edlPathFcp = "%s.xml" % edlPathBase if os.path.exists(edlPathAvid): edlPath = edlPathAvid elif os.path.exists(edlPathFcp): edlPath = edlPathFcp else: log("publishToFlix: Could not find EDL file for %s editorial asset." % assetName, "error") # Close the Editorial GUI sikuliUtils.closeChromeTab() # Come back to Flix self.launch.openFlixGUI(10) self.projectBrowser.loadShow() self.projectBrowser.loadSequence() click("loadLatestVersion.png") return # settings['edl'] = edlPath type(edlPath) type(sikuli.Key.TAB); wait(1) if toShotgun: type(sikuli.Key.SPACE); wait(1) type(sikuli.Key.TAB); wait(1) if branch != "main": type(sikuli.Key.ENTER); wait(1) type(sikuli.Key.TAB); wait(1) if not asStills: type(sikuli.Key.SPACE); wait(1) type(sikuli.Key.TAB); wait(1) type(comment); wait(1) type(sikuli.Key.TAB); wait(1) type(sikuli.Key.ENTER) loadLatestVersion = self.fromEditorialCheck.publishToFlixCheck2(comment, assetName, toShotgun, branch, asStills) # Close the Editorial GUI sikuliUtils.closeChromeTab() # Come back to Flix self.launch.openFlixGUI(10) self.projectBrowser.loadShow() self.projectBrowser.loadSequence() if branch != "main" and loadLatestVersion: self.projectBrowser.switchToBranch(branch) elif loadLatestVersion: click('loadLatestVersion.png') else: self.projectBrowser.createCleanVersion()