simplex 1.1.0__py3-none-any.whl → 1.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of simplex might be problematic. Click here for more details.

simplex/simplex.py CHANGED
@@ -3,7 +3,6 @@ from PIL import Image
3
3
  import requests
4
4
  from typing import List
5
5
  import io
6
- import time
7
6
 
8
7
  from .utils import center_bbox, screenshot_to_image
9
8
 
@@ -24,12 +23,15 @@ class Simplex:
24
23
  if browser is None:
25
24
  self.playwright = sync_playwright().start()
26
25
  self.browser = self.playwright.chromium.launch(headless=True)
26
+ self.driver = self.browser.new_page()
27
27
  else:
28
28
  self.playwright = None
29
-
30
- self.driver = self.browser.new_page(viewport={"width": 1280, "height": 720})
29
+ if len(self.browser.contexts) > 0 and len(self.browser.contexts[0].pages) > 0:
30
+ self.driver = self.browser.contexts[0].pages[0]
31
+ else:
32
+ self.driver = self.browser.new_page()
31
33
 
32
- def find_element(self, element_description: str, state: Image.Image | None = None, annotate: bool = False) -> List[int]:
34
+ def find_element(self, element_description: str, state: Image.Image | None = None, annotate: bool = True) -> List[int]:
33
35
  """
34
36
  Find an element in the screenshot using the element description
35
37
 
@@ -56,6 +58,7 @@ class Simplex:
56
58
  'element_description': (None, element_description),
57
59
  'api_key': (None, self.api_key)
58
60
  }
61
+
59
62
  # Make the request
60
63
  response = requests.post(
61
64
  endpoint,
@@ -83,20 +86,42 @@ class Simplex:
83
86
  // Create new overlay
84
87
  const overlay = document.createElement('div');
85
88
  overlay.id = 'simplex-bbox-overlay';
86
- overlay.style.position = 'absolute';
87
- overlay.style.border = '2px solid red';
89
+ overlay.style.position = 'fixed';
90
+ overlay.style.border = '2px dashed rgba(74, 144, 226, 1)';
91
+ overlay.style.background = 'rgba(74, 144, 226, 0.1)';
92
+ overlay.style.animation = 'marching-ants 0.5s linear infinite';
88
93
  overlay.style.left = bbox[0] + 'px';
89
94
  overlay.style.top = bbox[1] + 'px';
90
95
  overlay.style.width = (bbox[2] - bbox[0]) + 'px';
91
96
  overlay.style.height = (bbox[3] - bbox[1]) + 'px';
92
97
  overlay.style.pointerEvents = 'none';
93
98
  overlay.style.zIndex = '10000';
99
+ overlay.style.margin = '0';
100
+ overlay.style.padding = '0';
101
+
102
+ // Add marching ants animation keyframes
103
+ if (!document.querySelector('#marching-ants-keyframes')) {
104
+ const style = document.createElement('style');
105
+ style.id = 'marching-ants-keyframes';
106
+ style.textContent = `
107
+ @keyframes marching-ants {
108
+ 0% { border-style: dashed; }
109
+ 50% { border-style: solid; }
110
+ 100% { border-style: dashed; }
111
+ }
112
+ `;
113
+ document.head.appendChild(style);
114
+ }
94
115
 
95
116
  document.body.appendChild(overlay);
117
+
118
+ // Remove overlay after 3 second
119
+ setTimeout(() => {
120
+ overlay.remove();
121
+ }, 2000);
96
122
  }
97
123
  """, bbox)
98
124
  self.driver.wait_for_selector('#simplex-bbox-overlay')
99
- time.sleep(5)
100
125
  return bbox
101
126
  else:
102
127
  print("Error:", response.text)
@@ -147,13 +172,19 @@ class Simplex:
147
172
  print(response.text)
148
173
  return []
149
174
 
150
- def goto(self, url: str) -> None:
175
+ def goto(self, url: str, new_tab: bool = False) -> None:
151
176
  """
152
177
  Navigate to a URL
178
+
179
+ Args:
180
+ url (str): URL to navigate to
181
+ new_tab (bool): Whether to open a new tab or use the current tab
153
182
  """
183
+ if new_tab:
184
+ self.driver = self.browser.new_page()
154
185
  self.driver.goto(url)
155
186
 
156
- def execute_action(self, action: List[List[str]], state: Image.Image | None = None, annotate: bool = False) -> None:
187
+ def execute_action(self, action: List[List[str]], state: Image.Image | None = None, annotate: bool = True) -> None:
157
188
  """
158
189
  Execute an action with playwright driver
159
190
 
@@ -166,18 +197,21 @@ class Simplex:
166
197
 
167
198
  try:
168
199
  if action_type == "CLICK":
169
- bbox = self.find_element(description, state, annotate)
200
+ bbox = self.find_element(description, state, annotate=annotate)
170
201
  center_x, center_y = center_bbox(bbox)
171
202
  self.driver.mouse.click(center_x, center_y)
172
203
 
173
204
  elif action_type == "HOVER":
174
- bbox = self.find_element(description, state, annotate)
205
+ bbox = self.find_element(description, state, annotate=annotate)
175
206
  center_x, center_y = center_bbox(bbox)
176
207
  self.driver.mouse.move(center_x, center_y)
177
208
 
178
209
  elif action_type == "TYPE":
179
210
  self.driver.keyboard.type(description)
180
211
 
212
+ elif action_type == "ENTER":
213
+ self.driver.keyboard.press("Enter")
214
+
181
215
  elif action_type == "SCROLL":
182
216
  self.driver.mouse.wheel(0, int(description))
183
217
 
@@ -188,14 +222,14 @@ class Simplex:
188
222
  print(f"Error executing action: {e}")
189
223
  return None
190
224
 
191
- def do(self, step_description: str, annotate: bool = False) -> None:
225
+ def do(self, step_description: str, annotate: bool = True) -> None:
192
226
  """
193
227
  Execute a step description
194
228
  """
195
229
  state = self.take_stable_screenshot()
196
230
  actions = self.step_to_action(step_description, state)
197
231
  for action in actions:
198
- self.execute_action(action, annotate)
232
+ self.execute_action(action, annotate=annotate)
199
233
 
200
234
  def take_stable_screenshot(self) -> Image.Image:
201
235
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simplex
3
- Version: 1.1.0
3
+ Version: 1.2.1
4
4
  Summary: Official Python SDK for Simplex API
5
5
  Home-page: https://github.com/shreyka/simplex-python
6
6
  Author: Simplex Labs, Inc.
@@ -0,0 +1,10 @@
1
+ simplex/__init__.py,sha256=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
+ simplex/constants.py,sha256=nIXF2oVNNNknXweXAlmE-KBM9QjJtYw9osXVYjvloN0,59
3
+ simplex/simplex.py,sha256=8LTbvMJUbIWdyAqRKkius-R4PFHZBf4RW_bQZmwd5AY,9275
4
+ simplex/utils.py,sha256=UrD4Ena3yk0POmxxyiqMszzPbTscTCJpMP4xZFDAuOc,339
5
+ simplex-1.2.1.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
6
+ simplex-1.2.1.dist-info/METADATA,sha256=u9gF-wpSwjx0DfsrE5XM-7aRrmFyO5X-6LQ1RagF0tc,1114
7
+ simplex-1.2.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ simplex-1.2.1.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
9
+ simplex-1.2.1.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
10
+ simplex-1.2.1.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- simplex/__init__.py,sha256=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
- simplex/constants.py,sha256=nIXF2oVNNNknXweXAlmE-KBM9QjJtYw9osXVYjvloN0,59
3
- simplex/simplex.py,sha256=27knVLuna8Aab_7km_40v6SDTLfMO8jl8d-qWR21amA,7551
4
- simplex/utils.py,sha256=UrD4Ena3yk0POmxxyiqMszzPbTscTCJpMP4xZFDAuOc,339
5
- simplex-1.1.0.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
6
- simplex-1.1.0.dist-info/METADATA,sha256=BOck5V3dhKJbVd47mhX5BEwVVGieODpcQRxBbJuQy9o,1114
7
- simplex-1.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- simplex-1.1.0.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
9
- simplex-1.1.0.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
10
- simplex-1.1.0.dist-info/RECORD,,