robotframework-browser-tray 1.5.2__tar.gz → 1.6.1__tar.gz

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.
@@ -1,10 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: robotframework-browser-tray
3
- Version: 1.5.2
3
+ Version: 1.6.1
4
4
  Summary: Tray icon and REPL for trying out Browser Library keywords using Chromium or Edge
5
5
  Author-email: Marduk Bolaños <marduk.bolanos@imbus.de>
6
- Requires-Python: >=3.8.2
6
+ Requires-Python: >=3.9.0
7
7
  Description-Content-Type: text/markdown
8
+ Requires-Dist: psutil>=6.1.1
8
9
  Requires-Dist: pystray>=0.19.5
9
10
  Requires-Dist: robotframework-browser>=18.0.0
10
11
  Requires-Dist: robotframework-debug>=4.5.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "robotframework-browser-tray"
3
- version = "1.5.2"
3
+ version = "1.6.1"
4
4
  description = "Tray icon and REPL for trying out Browser Library keywords using Chromium or Edge"
5
5
  authors = [
6
6
  {name = "Marduk Bolaños", email = "marduk.bolanos@imbus.de"},
@@ -8,11 +8,12 @@ authors = [
8
8
  urls = { homepage = "https://github.com/mardukbp/robotframework-browser-tray" }
9
9
 
10
10
  dependencies = [
11
+ "psutil>=6.1.1",
11
12
  "pystray>=0.19.5",
12
13
  "robotframework-browser>=18.0.0",
13
14
  "robotframework-debug>=4.5.0",
14
15
  ]
15
- requires-python = ">=3.8.2"
16
+ requires-python = ">=3.9.0"
16
17
  readme = "README.md"
17
18
  license = {text = "Apache 2.0"}
18
19
 
@@ -31,7 +32,7 @@ dev = [
31
32
  ]
32
33
 
33
34
  [tool.pdm.scripts]
34
- test = "tox -p all"
35
+ test = "tox"
35
36
 
36
37
 
37
38
  [project.scripts]
@@ -0,0 +1,14 @@
1
+ from RobotDebug.RobotDebug import RobotDebug
2
+ from robot.libraries.BuiltIn import BuiltIn
3
+
4
+
5
+ class Repl(RobotDebug):
6
+ def __init__(self, playwright_process_port, remote_debugging_port, **kwargs):
7
+ super().__init__(**kwargs)
8
+
9
+ self.Library("Browser", "enable_presenter_mode=True", f"playwright_process_port={playwright_process_port}")
10
+ self.connect(remote_debugging_port)
11
+
12
+ def connect(self, remote_debugging_port):
13
+ BuiltIn().run_keyword("Connect To Browser", f"http://localhost:{remote_debugging_port}", "chromium", "use_cdp=True")
14
+ BuiltIn().run_keyword("Set Browser Timeout", "2s")
@@ -0,0 +1,144 @@
1
+ import http.client
2
+ import re
3
+ import socket
4
+ import sys
5
+ import tempfile
6
+ import time
7
+ from functools import wraps
8
+ from pathlib import Path
9
+ from textwrap import dedent
10
+
11
+ import psutil
12
+ import RobotDebug.styles
13
+ from Browser.base.librarycomponent import LibraryComponent
14
+ from robot.run import run_cli
15
+ from robot.api import logger
16
+
17
+ from BrowserTray.tray import get_ports
18
+
19
+
20
+ def escape_ansi(line):
21
+ ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
22
+ return ansi_escape.sub('', line)
23
+
24
+
25
+ print_output = RobotDebug.styles.print_output
26
+
27
+ @wraps(print_output)
28
+ def wrap_print_output(head, message, style=RobotDebug.styles.NORMAL_STYLE):
29
+ print_output(head, escape_ansi(message), style)
30
+
31
+ RobotDebug.styles.print_output = wrap_print_output
32
+
33
+
34
+ presenter_mode = LibraryComponent.presenter_mode
35
+
36
+ @wraps(presenter_mode)
37
+ def wrap_presenter_mode(self, selector, strict):
38
+ selector = self.resolve_selector(selector)
39
+ if self.library.presenter_mode:
40
+ mode = self.get_presenter_mode
41
+ try:
42
+ self.library.scroll_to_element(selector)
43
+ self.library.highlight_elements(
44
+ selector,
45
+ duration=mode["duration"],
46
+ width=mode["width"],
47
+ style=mode["style"],
48
+ color=mode["color"],
49
+ )
50
+ except Exception as error:
51
+ # selector = self.library.record_selector(f'"{selector}" failure')
52
+ logger.debug(f"On presenter more supress {error}")
53
+ else:
54
+ time.sleep(mode["duration"].seconds)
55
+ return selector
56
+
57
+ LibraryComponent.presenter_mode = wrap_presenter_mode
58
+
59
+
60
+ def test_suite(playwright_process_port, remote_debugging_port):
61
+ return bytes(dedent(
62
+ f"""
63
+ *** Settings ***
64
+ Library BrowserTray.Repl {playwright_process_port} {remote_debugging_port} repl=${True}
65
+
66
+ *** Test Cases ***
67
+ Robot Framework Debug REPL
68
+ Debug
69
+ """
70
+ ),
71
+ encoding='utf-8'
72
+ )
73
+
74
+
75
+ def shell(playwright_process_port, remote_debugging_port):
76
+ """A standalone robotframework shell."""
77
+
78
+ default_no_logs = [
79
+ "-l",
80
+ "None",
81
+ "-x",
82
+ "None",
83
+ "-o",
84
+ "None",
85
+ "-L",
86
+ "None",
87
+ "-r",
88
+ "None",
89
+ "--quiet",
90
+ ]
91
+
92
+ with tempfile.NamedTemporaryFile(
93
+ prefix="robot-debug-", suffix=".robot", delete=False
94
+ ) as test_file:
95
+ test_file.write(test_suite(playwright_process_port, remote_debugging_port))
96
+ test_file.flush()
97
+
98
+ if len(sys.argv) > 1:
99
+ args = sys.argv[1:] + [test_file.name]
100
+ else:
101
+ args = [*default_no_logs, test_file.name]
102
+
103
+ try:
104
+ sys.exit(run_cli(args))
105
+ finally:
106
+ test_file.close()
107
+ # pybot will raise PermissionError on Windows NT or later
108
+ # if NamedTemporaryFile called with `delete=True`,
109
+ # deleting test file seperated will be OK.
110
+ file_path = Path(test_file.name)
111
+ if file_path.exists():
112
+ file_path.unlink()
113
+
114
+
115
+ def run(timeout=0, test=False):
116
+ ports = []
117
+
118
+ if not test:
119
+ cmdline = [
120
+ proc.cmdline()
121
+ for proc in psutil.process_iter()
122
+ if proc.name() == 'browser-tray.exe'
123
+ ]
124
+
125
+ if not cmdline:
126
+ print("browser-tray must be running prior to executing ibrowser")
127
+ sys.exit(1)
128
+
129
+ _, *ports = cmdline[0]
130
+
131
+ playwright_process_port, remote_debugging_port = get_ports(ports)
132
+
133
+ try:
134
+ http.client.HTTPConnection('127.0.0.1', remote_debugging_port, timeout=1).connect()
135
+ if timeout:
136
+ time.sleep(timeout)
137
+ sys.exit(0)
138
+ shell(playwright_process_port, remote_debugging_port)
139
+ except socket.timeout:
140
+ print("ibrowser needs either:\n" +
141
+ " - a running Chromium, started using the tray icon or\n" +
142
+ " - a running Microsoft Edge started as explained in the documentation: https://pypi.org/project/robotframework-browser-tray/"
143
+ )
144
+ sys.exit(1)
@@ -6,6 +6,7 @@ import socket
6
6
  import subprocess
7
7
  import sys
8
8
  import time
9
+ import tkinter as tk
9
10
  from os.path import realpath
10
11
  from pathlib import Path
11
12
  from subprocess import Popen
@@ -109,7 +110,9 @@ class TrayIcon:
109
110
  chromium_dir = get_chromium_dir(node_modules)
110
111
 
111
112
  if not chromium_dir:
112
- messagebox.showerror("Error", "Chromium is not installed. Execute 'rfbrowser init chromium'.")
113
+ window = tk.Tk()
114
+ window.withdraw()
115
+ messagebox.showerror("Error", "Chromium is not installed. Execute 'rfbrowser init chromium'.", master=window)
113
116
  else:
114
117
  incognito_flag = ["-incognito"] if incognito else []
115
118
  chrome_exe = chromium_dir / "chrome-win" / "chrome.exe"
@@ -131,13 +134,13 @@ def is_running(cmd: str) -> bool:
131
134
  return len(instances) > 1
132
135
 
133
136
 
134
- def get_ports() -> Tuple[int, int]:
137
+ def get_ports(cmdline_args=None) -> Tuple[int, int]:
135
138
  MAX_PORT = 2**16
136
139
 
137
140
  arg_parser = argparse.ArgumentParser(add_help=True)
138
141
  arg_parser.add_argument("--pw-port", default=PLAYWRIGHT_PROCESS_PORT, type=int, help=f"Playwright process port (default: {PLAYWRIGHT_PROCESS_PORT})")
139
142
  arg_parser.add_argument("--cdp-port", default=REMOTE_DEBUGGING_PORT, type=int, help=f"Chromium debugging port (default: {REMOTE_DEBUGGING_PORT})")
140
- args = arg_parser.parse_args()
143
+ args = arg_parser.parse_args(cmdline_args)
141
144
  playwright_process_port = args.pw_port
142
145
  remote_debugging_port = args.cdp_port
143
146
 
@@ -165,7 +168,7 @@ def run():
165
168
 
166
169
  try:
167
170
  http.client.HTTPConnection('127.0.0.1', playwright_process_port, timeout=1).connect()
168
- print("The port 4711 is already in use. Either browser-tray is already running or another process is using the port.\n" +
171
+ print(f"The port {playwright_process_port} is already in use. Either browser-tray is already running or another process is using the port.\n" +
169
172
  "To start the Playwright wrapper on another port execute `browser-tray --pw-port PORT`")
170
173
  sys.exit(1)
171
174
  except socket.timeout:
@@ -1,13 +0,0 @@
1
- from RobotDebug.RobotDebug import RobotDebug
2
- from robot.libraries.BuiltIn import BuiltIn
3
-
4
-
5
- class Repl(RobotDebug):
6
- def __init__(self, **kwargs):
7
- super().__init__(**kwargs)
8
-
9
- self.Library("Browser", "enable_presenter_mode=True", "playwright_process_port=4711")
10
- self.connect()
11
-
12
- def connect(self):
13
- BuiltIn().run_keyword("Connect To Browser", "http://localhost:1234", "chromium", "use_cdp=True")
@@ -1,73 +0,0 @@
1
- import http.client
2
- import socket
3
- import sys
4
- import tempfile
5
- from pathlib import Path
6
- import time
7
-
8
- from robot import run_cli
9
-
10
-
11
- TEST_SUITE = b"""
12
- *** Settings ***
13
- Library BrowserTray.Repl repl=${True}
14
-
15
- *** Test Cases ***
16
- Robot Framework Debug REPL
17
- Debug
18
- """
19
-
20
-
21
- def shell():
22
- """A standalone robotframework shell."""
23
-
24
- default_no_logs = [
25
- "-l",
26
- "None",
27
- "-x",
28
- "None",
29
- "-o",
30
- "None",
31
- "-L",
32
- "None",
33
- "-r",
34
- "None",
35
- "--quiet",
36
- ]
37
-
38
- with tempfile.NamedTemporaryFile(
39
- prefix="robot-debug-", suffix=".robot", delete=False
40
- ) as test_file:
41
- test_file.write(TEST_SUITE)
42
- test_file.flush()
43
-
44
- if len(sys.argv) > 1:
45
- args = sys.argv[1:] + [test_file.name]
46
- else:
47
- args = [*default_no_logs, test_file.name]
48
-
49
- try:
50
- sys.exit(run_cli(args))
51
- finally:
52
- test_file.close()
53
- # pybot will raise PermissionError on Windows NT or later
54
- # if NamedTemporaryFile called with `delete=True`,
55
- # deleting test file seperated will be OK.
56
- file_path = Path(test_file.name)
57
- if file_path.exists():
58
- file_path.unlink()
59
-
60
-
61
- def run(timeout=0):
62
- try:
63
- http.client.HTTPConnection('127.0.0.1', 1234, timeout=1).connect()
64
- if timeout:
65
- time.sleep(timeout)
66
- sys.exit(0)
67
- shell()
68
- except socket.timeout:
69
- print("ibrowser needs either:\n" +
70
- " - a running Chromium, started using the tray icon or\n" +
71
- " - a running Microsoft Edge started as explained in the documentation: https://pypi.org/project/robotframework-browser-tray/"
72
- )
73
- sys.exit(1)