diff --git a/coverage.svg b/coverage.svg
index d79e240..eb83f3f 100644
--- a/coverage.svg
+++ b/coverage.svg
@@ -9,13 +9,13 @@
-
+
coverage
coverage
- 65%
- 65%
+ 59%
+ 59%
diff --git a/lackey/ImportHandler.py b/lackey/ImportHandler.py
new file mode 100644
index 0000000..d48ed9a
--- /dev/null
+++ b/lackey/ImportHandler.py
@@ -0,0 +1,56 @@
+import sys
+import os.path
+
+if sys.version_info[0] == 3:
+ from importlib.abc import MetaPathFinder
+ from importlib.util import spec_from_file_location
+ from importlib.machinery import SourceFileLoader
+
+ class SikuliFinder(MetaPathFinder):
+ def find_spec(self, fullname, path, target=None):
+ if "." in fullname:
+ name = fullname.split(".")[-1]
+ else:
+ name = fullname
+ for entry in sys.path:
+ if entry == "":
+ entry = os.getcwd()
+ sikuli_path = os.path.join(entry, "{}.sikuli".format(name))
+ filename = os.path.join(sikuli_path, "{}.py".format(name))
+ if not os.path.exists(filename):
+ continue
+
+ # Found what we're looking for. Add to path.
+ sys.path.append(sikuli_path)
+
+ return spec_from_file_location(fullname, filename, loader=SourceFileLoader(fullname, filename),
+ submodule_search_locations=None)
+
+ return None # we don't know how to import this
+ sys.meta_path.append(SikuliFinder())
+elif sys.version_info[0] == 2:
+ import imp
+
+ class SikuliFinder(object):
+ def __init__(self, path):
+ self.path = path
+
+ @classmethod
+ def find_module(cls, name, path=None):
+ for entry in sys.path:
+ sikuli_path = os.path.join(entry, "{}.sikuli".format(name))
+ filename = os.path.join(sikuli_path, "{}.py".format(name))
+ if not os.path.exists(filename):
+ continue
+
+ # Found what we're looking for. Add to path.
+ sys.path.append(sikuli_path)
+ return cls(filename)
+
+ def load_module(self, name):
+ if name in sys.modules:
+ return sys.modules[name]
+ with open(self.path, "r") as project:
+ mod = imp.load_module(name, project, self.path, (".py", "r", imp.PY_SOURCE))
+ return mod
+ sys.meta_path.append(SikuliFinder)
\ No newline at end of file
diff --git a/lackey/RegionMatching.py b/lackey/RegionMatching.py
index e1988b0..2061314 100644
--- a/lackey/RegionMatching.py
+++ b/lackey/RegionMatching.py
@@ -99,7 +99,7 @@ def setFilename(self, filename):
""" Set the filename of the pattern's image (and load it) """
## Loop through image paths to find the image
found = False
- for image_path in [Settings.BundlePath, os.getcwd()] + Settings.ImagePaths:
+ for image_path in sys.path + [Settings.BundlePath, os.getcwd()] + Settings.ImagePaths:
full_path = os.path.join(image_path, filename)
if os.path.exists(full_path):
# Image file not found
@@ -1015,33 +1015,38 @@ def write(self, text):
def delayType(millisecs):
Settings.TypeDelay = millisecs
def isRegionValid(self):
- """ Returns false if the whole region is outside any screen, otherwise true """
+ """ Returns false if the whole region is not even partially inside any screen, otherwise true """
screens = PlatformManager.getScreenDetails()
for screen in screens:
s_x, s_y, s_w, s_h = screen["rect"]
- if (self.x+self.w < s_x or s_x+s_w < self.x or self.y+self.h < s_y or s_y+s_h < self.y):
+ if self.x+self.w >= s_x and s_x+s_w >= self.x and self.y+self.h >= s_y and s_y+s_h >= self.y:
# Rects overlap
- return False
- return True
+ return True
+ return False
def clipRegionToScreen(self):
""" Returns the part of the region that is visible on a screen
+ If the region equals to all visible screens, returns Screen(-1).
If the region is visible on multiple screens, returns the screen with the smallest ID.
Returns None if the region is outside the screen.
"""
if not self.isRegionValid():
return None
screens = PlatformManager.getScreenDetails()
+ total_x, total_y, total_w, total_h = Screen(-1).getBounds()
containing_screen = None
for screen in screens:
s_x, s_y, s_w, s_h = screen["rect"]
if self.x >= s_x and self.x+self.w <= s_x+s_w and self.y >= s_y and self.y+self.h <= s_y+s_h:
# Region completely inside screen
return self
- elif self.x+self.w < s_x or s_x+s_w < self.x or self.y+self.h < s_y or s_y+s_h < self.y:
+ elif self.x+self.w <= s_x or s_x+s_w <= self.x or self.y+self.h <= s_y or s_y+s_h <= self.y:
# Region completely outside screen
continue
+ elif self.x == total_x and self.y == total_y and self.w == total_w and self.h == total_h:
+ # Region equals all screens, Screen(-1)
+ return self
else:
# Region partially inside screen
x = max(self.x, s_x)
@@ -1903,7 +1908,7 @@ def showMonitors(cls):
Debug.info("*** monitor configuration [ {} Screen(s)] ***".format(cls.getNumberScreens()))
Debug.info("*** Primary is Screen {}".format(cls.primaryScreen))
for index, screen in enumerate(PlatformManager.getScreenDetails()):
- Debug.info("Screen {}: ({}, {}, {}, {})".format(index, *screen[rect]))
+ Debug.info("Screen {}: ({}, {}, {}, {})".format(index, *screen["rect"]))
Debug.info("*** end monitor configuration ***")
def resetMonitors(self):
""" Recalculates screen based on changed monitor setup """
diff --git a/lackey/__init__.py b/lackey/__init__.py
index 7e76eb4..a4ff92f 100644
--- a/lackey/__init__.py
+++ b/lackey/__init__.py
@@ -38,6 +38,8 @@
from .SikuliGui import PopupInput, PopupList, PopupTextarea
from ._version import __version__
+from . import ImportHandler
+
VALID_PLATFORMS = ["Windows", "Darwin"]
## Define script abort hotkey (Alt+Shift+C)
diff --git a/lackey/_version.py b/lackey/_version.py
index 39c4d75..7bf37e0 100644
--- a/lackey/_version.py
+++ b/lackey/_version.py
@@ -2,5 +2,5 @@
"""
-__version__ = "0.7.0"
+__version__ = "0.7.1"
__sikuli_version__ = "1.1.0"
diff --git a/tests/preview_open_2.png b/tests/preview_open_2.png
new file mode 100644
index 0000000..9c50113
Binary files /dev/null and b/tests/preview_open_2.png differ
diff --git a/tests/test_cases.py b/tests/test_cases.py
index 4d0a816..9f6df5d 100644
--- a/tests/test_cases.py
+++ b/tests/test_cases.py
@@ -70,6 +70,15 @@ def setUp(self):
lackey.Screen(0).hover()
lackey.Screen(0).click()
+ def testImporter(self):
+ """ Tries to import the test_cases project file
+ (ignores FindFailed exception thrown by project) """
+ try:
+ sys.path.append(os.path.join(os.getcwd(), "tests"))
+ import test_import
+ except lackey.FindFailed:
+ pass
+
def testTypeCopyPaste(self):
""" Also tests the log file """
lackey.Debug.setLogFile("logfile.txt")
@@ -90,8 +99,8 @@ def testTypeCopyPaste(self):
app = lackey.App("+open -e")
lackey.sleep(2)
#r.debugPreview()
- r.wait(lackey.Pattern("preview_open.png"), lackey.FOREVER)
- r.click(lackey.Pattern("preview_open.png"))
+ r.wait(lackey.Pattern("preview_open_2.png"))
+ r.click(lackey.Pattern("preview_open_2.png"))
lackey.type("n", lackey.KeyModifier.CMD)
time.sleep(1)
app = lackey.App("Untitled")
@@ -129,7 +138,7 @@ def test_observer(appear_event):
r.doubleClick("notepad.png")
elif sys.platform == "darwin":
r.doubleClick("textedit.png")
- r.wait("preview_open.png")
+ r.wait("preview_open_2.png")
r.type("n", lackey.KeyModifier.CMD)
time.sleep(2)
r.type("This is a test")
@@ -153,7 +162,7 @@ def test_observer(appear_event):
r.type("{F4}", lackey.Key.ALT)
elif sys.platform == "darwin":
r.type("w", lackey.KeyModifier.CMD)
- r.click(lackey.Pattern("textedit_save.png").targetOffset(-86, 41))
+ r.click(lackey.Pattern("textedit_save_2.png").targetOffset(-86, 25))
lackey.sleep(0.5)
r.type("q", lackey.KeyModifier.CMD)
diff --git a/tests/test_import.sikuli/1514401659995.png b/tests/test_import.sikuli/1514401659995.png
new file mode 100755
index 0000000..5b336fc
Binary files /dev/null and b/tests/test_import.sikuli/1514401659995.png differ
diff --git a/tests/test_import.sikuli/test.html b/tests/test_import.sikuli/test.html
new file mode 100755
index 0000000..89a25ac
--- /dev/null
+++ b/tests/test_import.sikuli/test.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+find()
+
+
+
diff --git a/tests/test_import.sikuli/test_import.py b/tests/test_import.sikuli/test_import.py
new file mode 100755
index 0000000..6431bf1
--- /dev/null
+++ b/tests/test_import.sikuli/test_import.py
@@ -0,0 +1,4 @@
+import sys
+from lackey import *
+
+find("1514401659995.png")
diff --git a/tests/textedit_save_2.png b/tests/textedit_save_2.png
new file mode 100644
index 0000000..fcb0a94
Binary files /dev/null and b/tests/textedit_save_2.png differ