def run(self): """Runs the installer.""" self._ensure(running=False) _LOGGER.info('Running %s', self.path) openApp(self.path) self.running = True self.installing = False self.anchor(WELCOME_WINDOW_TIMEOUT) _LOGGER.info('Installer window has appeared') self.page = self.welcome_page self.button_region = Region( self.getX(), self.getY() + self.getH() - BUTTON_REGION_HEIGHT, self.getW(), BUTTON_REGION_HEIGHT) self.buttons = Buttons(self.button_images, self.disabled_button_images, region=self.button_region) self.buttons.find_buttons() self.buttons_valid = True self.buttons.waitUntilButtonIsEnabled('next', NEXT_BUTTON_ENABLED_TIMEOUT) self.confirm_window_open = False self.confirm_window_region = Region( self.getX() + (self.getW() - CONFIRM_WINDOW_WIDTH) / 2, self.getY() + (self.getH() - CONFIRM_WINDOW_HEIGHT) / 2, CONFIRM_WINDOW_WIDTH, CONFIRM_WINDOW_HEIGHT) self.confirm_buttons = Buttons(self.confirm_button_images, region=self.confirm_window_region) _LOGGER.info('Waiting for Next button to be enabled') self.shortcut_checkboxes = None
def update_button(self, name): """Updates the specified button so that this button set reflects the current state of the button. """ _LOGGER.debug("%sgetting current state of '%s' button", self._debugprefix, name) i, match = self._button_matches[name] button_region = Region(match).nearby(15) images = [] images.extend(self._buttons[name]) if self._disabled_buttons is not None and \ name in self._disabled_buttons: images.extend(self._disabled_buttons[name]) i_best, m_best = bestMatch(images, region=button_region, minOverlap=0.5) disabled = i_best >= len(self._buttons[name]) if disabled: _LOGGER.info("'%s' button (image %d) is disabled", name, i_best - len(self._buttons[name])) s = self._disabled_button_index[name] self._button_matches[name] = \ (s + i_best - len(self._buttons[name]), m_best) else: _LOGGER.info("'%s' button (image %d) is enabled", name, i_best) s = self._button_index[name] self._button_matches[name] = (s + i_best, m_best)
def waitUntilComplete(self, timeout=60, resultArgs={}): self.validate() # Convert Match to Region -> workaround: https://bugs.launchpad.net/sikuli/+bug/905435 r = Region(self.region) r.onChange(self.__changed) r.observe(FOREVER, background=True) # start observing progress bar startTime = time.time() self.lastChange = time.time() # loop while things are still changing while (time.time() - self.lastChange) < timeout: sleep(1) r.stopObserver() # stop observing progress bar self.logger.trace("stopped changing after %ds" % (time.time() - startTime)) # try and click the button state = "complete" ir = self.regionFinder(self, region=self.region, state=state) # image region of the button try: region = ir.find() except FindExhaustedException, e: raise StateFailedException("incorrect state [%s]" % state)
def _add_match(self, match, state, regions, checked_region_scores, unchecked_region_scores): """Find the region in regions that is similar to the match. Update the score for that region. If there is no similar region, create a new region from the match. """ match_region = None for region in regions: if sameRegion(region, match, 0.5): match_region = region break if match_region is None: match_region = Region(match) regions.append(match_region) region_id = self._region_id(match_region) if region_id not in checked_region_scores: checked_region_scores[region_id] = 0 if region_id not in unchecked_region_scores: unchecked_region_scores[region_id] = 0 if state == 'checked': if match.getScore() > checked_region_scores[region_id]: checked_region_scores[region_id] = match.getScore() else: if match.getScore() > unchecked_region_scores[region_id]: unchecked_region_scores[region_id] = match.getScore()
def goto(self, x, y): if self.enabled: self.queue.append([x, y]) if not self.region: self.region = Region(x, y, 1, 1) else: self.region = self.region.add(Location(x, y))
def __init__(self, region, title): """Creates a new window that covers the specified region. The region includes the title bar. """ self.region = region self.title = title self.titlebar_region = Region(region.getX(), region.getY(), region.getW(), windowflavor.WINDOW_TITLEBAR_HEIGHT) self.minimize_button = self.getButtonLocation( windowflavor.WINDOW_TITLEBAR_MINIMIZE_BUTTON_OFFSET) self.maximize_button = self.getButtonLocation( windowflavor.WINDOW_TITLEBAR_MAXIMIZE_BUTTON_OFFSET) self.close_button = self.getButtonLocation( windowflavor.WINDOW_TITLEBAR_CLOSE_BUTTON_OFFSET)
def update_element(self, element_index): """Updates the specified element with its true state. """ region = Region(self.element_regions[element_index]) # add some space since images may have slightly different size marginx = int(region.getW() * 0.2) marginy = int(region.getH() * 0.2) extendRegion(region, left=marginx, right=marginx, top=marginy, bottom=marginy) best_checked_score = 0 best_unchecked_score = 0 try: best_checked = bestMatch(self.images['checked'], region=region, minOverlap=0.5) if best_checked is not None: best_checked_score = best_checked[1].getScore() except FindFailed: pass try: best_unchecked = bestMatch(self.images['unchecked'], region=region, minOverlap=0.5) if best_unchecked is not None: best_unchecked_score = best_unchecked[1].getScore() except FindFailed: pass if best_checked_score == best_unchecked_score: if best_checked_score == 0: raise Exception('no %s found in region %d' % (self.element_types, element_index)) raise Exception( 'score tie: cannot decide whether %s %d is checked or unchecked (score=%f)' % (self.element_type, element_index, best_checked_score)) state = best_checked_score > best_unchecked_score if state != self.is_checked(element_index): self._toggle_state(element_index)
def testCanDisplayRegion(self): # Should have simplified Region coords and a md5 of active region formatter = Formatter(Region(0, 0, 100, 100)) self.assertEqual(str(formatter), '["Region[0,0 100x100]"](md5.png:Actual)')
def goto(self, x, y): if not self.region: self.region = Region(x, y, 1, 1) else: self.region = self.region.add(Location(x,y))
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ # TODO: copied from windowsxp.py, need to fix! from sikuli.Region import Region from sikuli.Sikuli import SCREEN """Window theme """ WINDOW_TITLEBAR_HEIGHT = 30 WINDOW_TITLEBAR_MINIMIZE_BUTTON_OFFSET = -62 WINDOW_TITLEBAR_MAXIMIZE_BUTTON_OFFSET = -39 WINDOW_TITLEBAR_CLOSE_BUTTON_OFFSET = -16 """Windows task bar """ WINDOWS_TASKBAR_REGION = Region(0, SCREEN.getH() - 31, SCREEN.getW(), 31) """Paths """ INTERNET_EXPLORER_PATH = r'C:\Program Files\Internet Explorer\IEXPLORE.EXE' MSOFFICE_ROOT_PATH = r'C:\Program Files\Microsoft Office' WINDOWS_EXPLORER_PATH = r'C:\WINDOWS\explorer.exe' CONTROL_PANEL_PATH = r'C:\WINDOWS\system32\control.exe' NOTEPAD_PATH = r'C:\WINDOWS\system32\notepad.exe'
def performFind(self): """ Loads the baseline images from disk and finds them on the screen. Works with the Transforms class to load extra data stored in the PNG's to control how they're matched. """ # sequence and series for series in self.seriesRange: regions = [] lastRegion = self.region nextRegion = Region(self.region) # try to match all images in the sequence try: for (sequence, filename) in enumerate( self.getImageNames(series=series, state=self.state)): transform = self.transform(filename, entity=self.entity, regionsMatched=regions, context=self) # Apply prev search attribs nextRegion = transform.apply( nextRegion, self.transform.CONTEXT_PREVIOUS) # Apply search attribs pattern = transform.apply(Pattern(filename), self.transform.CONTEXT_CURRENT) self.logger.trace("Loading %%s", self.logger.getFormatter()(pattern)) # find the image on the screen lastRegion = nextRegion.wait( pattern ) # If we don't set to zero wait time (dialog handler threads wait indefinitely) lastRegion = transform.apply(lastRegion, self.transform.CONTEXT_MATCH) self.logger.trace( "validated %%s %%s in region %%s nameType=%s colType=%s ser=%s seq=%s" % (self.nameType, self.collectionType, series, sequence), self.logger.getFormatter()(pattern), self.logger.getFormatter()(lastRegion), self.logger.getFormatter()(nextRegion)) regions.append(lastRegion) # Transform next region with the spacial region # spacialRegion is only used if there are spacial modifiers nextRegion = transform.apply(Region(nextRegion), self.transform.CONTEXT_NEXT, override=lastRegion) except FindFailed, e: self.logger.trace( "failed to find on screen %%s in %%s nameType=%s colType=%s ser=%s seq=%s" % (self.nameType, self.collectionType, series, sequence), self.logger.getFormatter()(self).setLabel("Images"), self.logger.getFormatter()(nextRegion)) else: region = None for currentRegion in regions: if not region: region = Region(currentRegion) else: region.add(currentRegion) region = transform.apply(region, self.transform.CONTEXT_FINAL) # Apply entity transforms transform.apply(self.entity, self.transform.CONTEXT_ENTITY) self.lastRegionFound = region self.lastSeriesFound = series return region
def getLastRegionMatched(self): return Region(0, 0, 100, 100)
def getLastRegionFound(self): return Region(0, 0, 100, 100)
def find(self, timeout=0): return Region(0, 0, 100, 100)