robotframework-browser-tray 1.6.0__tar.gz → 1.7.0__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.
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/PKG-INFO +5 -5
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/README.md +2 -2
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/pyproject.toml +3 -3
- robotframework_browser_tray-1.7.0/src/BrowserTray/BrowserRepl/__init__.py +14 -0
- robotframework_browser_tray-1.7.0/src/BrowserTray/cmdline_args.py +22 -0
- robotframework_browser_tray-1.7.0/src/BrowserTray/ibrowser/__init__.py +1 -0
- {robotframework_browser_tray-1.6.0/src/BrowserTray/Repl → robotframework_browser_tray-1.7.0/src/BrowserTray/ibrowser}/repl.py +37 -17
- robotframework_browser_tray-1.7.0/src/BrowserTray/playwright.py +44 -0
- robotframework_browser_tray-1.7.0/src/BrowserTray/tray.py +114 -0
- robotframework_browser_tray-1.6.0/src/BrowserTray/Repl/__init__.py +0 -13
- robotframework_browser_tray-1.6.0/src/BrowserTray/tray.py +0 -176
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/__init__.py +0 -0
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/__main__.py +0 -0
- {robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/chromium.png +0 -0
- {robotframework_browser_tray-1.6.0/src/BrowserTray/Repl → robotframework_browser_tray-1.7.0/src/BrowserTray/ibrowser}/__main__.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: robotframework-browser-tray
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
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.
|
|
6
|
+
Requires-Python: >=3.9.0
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: pystray>=0.19.5
|
|
9
9
|
Requires-Dist: robotframework-browser>=18.0.0
|
|
@@ -51,7 +51,7 @@ python -m BrowserTray
|
|
|
51
51
|
**Hint**: In case your environment does not allow executing ibrowser, call the Python module directly:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
python -m BrowserTray.
|
|
54
|
+
python -m BrowserTray.ibrowser
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
### ibrowser
|
|
@@ -103,7 +103,7 @@ If Microsoft Edge is installed on your machine:
|
|
|
103
103
|
|
|
104
104
|
## How it works
|
|
105
105
|
|
|
106
|
-
On start up `
|
|
106
|
+
On start up `ibrowser` checks whether `rfbrowser init` has been executed.
|
|
107
107
|
|
|
108
108
|
If this requirement is met the Playwright wrapper is started with `node site-packages/Browser/wrapper/index.js 4711`.
|
|
109
109
|
|
|
@@ -39,7 +39,7 @@ python -m BrowserTray
|
|
|
39
39
|
**Hint**: In case your environment does not allow executing ibrowser, call the Python module directly:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
python -m BrowserTray.
|
|
42
|
+
python -m BrowserTray.ibrowser
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### ibrowser
|
|
@@ -91,7 +91,7 @@ If Microsoft Edge is installed on your machine:
|
|
|
91
91
|
|
|
92
92
|
## How it works
|
|
93
93
|
|
|
94
|
-
On start up `
|
|
94
|
+
On start up `ibrowser` checks whether `rfbrowser init` has been executed.
|
|
95
95
|
|
|
96
96
|
If this requirement is met the Playwright wrapper is started with `node site-packages/Browser/wrapper/index.js 4711`.
|
|
97
97
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "robotframework-browser-tray"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.7.0"
|
|
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"},
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"robotframework-browser>=18.0.0",
|
|
13
13
|
"robotframework-debug>=4.5.0",
|
|
14
14
|
]
|
|
15
|
-
requires-python = ">=3.
|
|
15
|
+
requires-python = ">=3.9.0"
|
|
16
16
|
readme = "README.md"
|
|
17
17
|
license = {text = "Apache 2.0"}
|
|
18
18
|
|
|
@@ -36,7 +36,7 @@ test = "tox"
|
|
|
36
36
|
|
|
37
37
|
[project.scripts]
|
|
38
38
|
browser-tray = "BrowserTray.tray:run"
|
|
39
|
-
ibrowser = "BrowserTray.
|
|
39
|
+
ibrowser = "BrowserTray.ibrowser:run"
|
|
40
40
|
|
|
41
41
|
[build-system]
|
|
42
42
|
requires = ["flit_core>=3.2,<4"]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from RobotDebug.RobotDebug import RobotDebug
|
|
2
|
+
from robot.libraries.BuiltIn import BuiltIn
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BrowserRepl(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,22 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from typing import Tuple
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
REMOTE_DEBUGGING_PORT = 1234
|
|
6
|
+
PLAYWRIGHT_PROCESS_PORT= 4711
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_ports() -> Tuple[int, int]:
|
|
10
|
+
MAX_PORT = 2**16
|
|
11
|
+
|
|
12
|
+
arg_parser = argparse.ArgumentParser(add_help=True)
|
|
13
|
+
arg_parser.add_argument("--pw-port", default=PLAYWRIGHT_PROCESS_PORT, type=int, help=f"Playwright process port (default: {PLAYWRIGHT_PROCESS_PORT})")
|
|
14
|
+
arg_parser.add_argument("--cdp-port", default=REMOTE_DEBUGGING_PORT, type=int, help=f"Chromium debugging port (default: {REMOTE_DEBUGGING_PORT})")
|
|
15
|
+
args = arg_parser.parse_args()
|
|
16
|
+
playwright_process_port = args.pw_port
|
|
17
|
+
remote_debugging_port = args.cdp_port
|
|
18
|
+
|
|
19
|
+
if playwright_process_port > MAX_PORT or remote_debugging_port > MAX_PORT:
|
|
20
|
+
raise ValueError(f"Port numbers cannot be larger than {MAX_PORT}")
|
|
21
|
+
|
|
22
|
+
return (playwright_process_port, remote_debugging_port)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .repl import run
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import http.client
|
|
2
2
|
import re
|
|
3
3
|
import socket
|
|
4
|
+
from subprocess import Popen
|
|
4
5
|
import sys
|
|
5
6
|
import tempfile
|
|
6
7
|
import time
|
|
7
8
|
from functools import wraps
|
|
8
9
|
from pathlib import Path
|
|
10
|
+
from textwrap import dedent
|
|
9
11
|
|
|
10
12
|
import RobotDebug.styles
|
|
11
13
|
from Browser.base.librarycomponent import LibraryComponent
|
|
12
14
|
from robot.run import run_cli
|
|
13
15
|
from robot.api import logger
|
|
14
16
|
|
|
17
|
+
from BrowserTray import cmdline_args
|
|
18
|
+
from BrowserTray import playwright
|
|
19
|
+
|
|
15
20
|
|
|
16
21
|
def escape_ansi(line):
|
|
17
22
|
ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
|
|
@@ -53,17 +58,22 @@ def wrap_presenter_mode(self, selector, strict):
|
|
|
53
58
|
LibraryComponent.presenter_mode = wrap_presenter_mode
|
|
54
59
|
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
def test_suite(playwright_process_port, remote_debugging_port):
|
|
62
|
+
return bytes(dedent(
|
|
63
|
+
f"""
|
|
64
|
+
*** Settings ***
|
|
65
|
+
Library BrowserTray.BrowserRepl {playwright_process_port} {remote_debugging_port} repl=${True}
|
|
59
66
|
|
|
60
|
-
*** Test Cases ***
|
|
61
|
-
Robot Framework Debug REPL
|
|
62
|
-
|
|
63
|
-
"""
|
|
67
|
+
*** Test Cases ***
|
|
68
|
+
Robot Framework Debug REPL
|
|
69
|
+
Debug
|
|
70
|
+
"""
|
|
71
|
+
),
|
|
72
|
+
encoding='utf-8'
|
|
73
|
+
)
|
|
64
74
|
|
|
65
75
|
|
|
66
|
-
def
|
|
76
|
+
def irobot(testsuite: bytes, playwright_proc: Popen):
|
|
67
77
|
"""A standalone robotframework shell."""
|
|
68
78
|
|
|
69
79
|
default_no_logs = [
|
|
@@ -83,15 +93,21 @@ def shell():
|
|
|
83
93
|
with tempfile.NamedTemporaryFile(
|
|
84
94
|
prefix="robot-debug-", suffix=".robot", delete=False
|
|
85
95
|
) as test_file:
|
|
86
|
-
test_file.write(
|
|
96
|
+
test_file.write(testsuite)
|
|
87
97
|
test_file.flush()
|
|
88
98
|
|
|
89
99
|
if len(sys.argv) > 1:
|
|
90
|
-
|
|
100
|
+
sys.argv = [
|
|
101
|
+
arg
|
|
102
|
+
for arg in sys.argv
|
|
103
|
+
if not (arg.startswith('--pw-port') or arg.startswith('--cdp-port'))
|
|
104
|
+
]
|
|
105
|
+
args = sys.argv[1:] + [*default_no_logs, test_file.name]
|
|
91
106
|
else:
|
|
92
107
|
args = [*default_no_logs, test_file.name]
|
|
93
108
|
|
|
94
109
|
try:
|
|
110
|
+
|
|
95
111
|
sys.exit(run_cli(args))
|
|
96
112
|
finally:
|
|
97
113
|
test_file.close()
|
|
@@ -101,18 +117,22 @@ def shell():
|
|
|
101
117
|
file_path = Path(test_file.name)
|
|
102
118
|
if file_path.exists():
|
|
103
119
|
file_path.unlink()
|
|
120
|
+
|
|
121
|
+
playwright_proc.terminate()
|
|
122
|
+
|
|
104
123
|
|
|
124
|
+
def run():
|
|
125
|
+
playwright_process_port, remote_debugging_port = cmdline_args.get_ports()
|
|
105
126
|
|
|
106
|
-
def run(timeout=0):
|
|
107
127
|
try:
|
|
108
|
-
http.client.HTTPConnection('127.0.0.1',
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
shell()
|
|
128
|
+
http.client.HTTPConnection('127.0.0.1', remote_debugging_port, timeout=1).connect()
|
|
129
|
+
|
|
130
|
+
playwright_proc = playwright.run(playwright_process_port)
|
|
131
|
+
irobot(test_suite(playwright_process_port, remote_debugging_port), playwright_proc)
|
|
113
132
|
except socket.timeout:
|
|
114
133
|
print("ibrowser needs either:\n" +
|
|
115
134
|
" - a running Chromium, started using the tray icon or\n" +
|
|
116
|
-
" - a running Microsoft Edge started as explained in the documentation: https://pypi.org/project/robotframework-browser-tray
|
|
135
|
+
" - a running Microsoft Edge started as explained in the documentation: https://pypi.org/project/robotframework-browser-tray/\n" +
|
|
136
|
+
f"Default remote-debugging-port: {remote_debugging_port}"
|
|
117
137
|
)
|
|
118
138
|
sys.exit(1)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import http.client
|
|
2
|
+
import site
|
|
3
|
+
import socket
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from subprocess import Popen
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_, site_packages = site.getsitepackages()
|
|
11
|
+
browser_wrapper = Path(site_packages) / "Browser" / "wrapper"
|
|
12
|
+
index_js = browser_wrapper / "index.js"
|
|
13
|
+
node_modules = browser_wrapper / "node_modules"
|
|
14
|
+
playwright_core = node_modules / "playwright-core"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def playwright_is_initialized():
|
|
18
|
+
return node_modules.is_dir() and playwright_core.is_dir()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def start_playwright(playwright_process_port: int) -> Popen:
|
|
22
|
+
return Popen(
|
|
23
|
+
['node', index_js, str(playwright_process_port)],
|
|
24
|
+
stderr=subprocess.PIPE,
|
|
25
|
+
stdout=subprocess.PIPE
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def run(playwright_process_port: int) -> Popen:
|
|
30
|
+
if not playwright_is_initialized():
|
|
31
|
+
print(
|
|
32
|
+
"Playwright has not been initialized.\n" +
|
|
33
|
+
"In order to use Chromium execute 'rfbrowser init chromium'.\n" +
|
|
34
|
+
"If you want to use the Microsoft Edge installed on your system execute 'rfbrowser init --skip-browsers'"
|
|
35
|
+
)
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
http.client.HTTPConnection('127.0.0.1', playwright_process_port, timeout=1).connect()
|
|
40
|
+
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" +
|
|
41
|
+
"To start the Playwright wrapper on another port execute `browser-tray --pw-port PORT`")
|
|
42
|
+
sys.exit(1)
|
|
43
|
+
except socket.timeout:
|
|
44
|
+
return start_playwright(playwright_process_port)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import site
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import tkinter as tk
|
|
6
|
+
from os.path import realpath
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from subprocess import Popen
|
|
9
|
+
from tkinter import messagebox
|
|
10
|
+
from typing import List
|
|
11
|
+
|
|
12
|
+
from PIL import Image
|
|
13
|
+
from pystray import Icon, Menu, MenuItem
|
|
14
|
+
|
|
15
|
+
from BrowserTray import cmdline_args
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_, site_packages = site.getsitepackages()
|
|
19
|
+
browser_wrapper = Path(site_packages).resolve() / "Browser" / "wrapper"
|
|
20
|
+
index_js = browser_wrapper / "index.js"
|
|
21
|
+
node_modules = browser_wrapper / "node_modules"
|
|
22
|
+
playwright_core = node_modules / "playwright-core"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def find_chromium(path: Path) -> List[Path]:
|
|
26
|
+
return [
|
|
27
|
+
Path(file.path)
|
|
28
|
+
for file in os.scandir(path)
|
|
29
|
+
if file.is_dir() and file.name.startswith("chromium")
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_chromium_dir(node_modules: Path):
|
|
34
|
+
local_browsers = playwright_core / ".local-browsers"
|
|
35
|
+
|
|
36
|
+
if not (node_modules.is_dir() and local_browsers.is_dir() and find_chromium(local_browsers)):
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
return find_chromium(local_browsers)[0]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def start_chromium(remote_debugging_port: int, incognito: bool):
|
|
43
|
+
chromium_dir = get_chromium_dir(node_modules)
|
|
44
|
+
|
|
45
|
+
if not chromium_dir:
|
|
46
|
+
window = tk.Tk()
|
|
47
|
+
window.withdraw()
|
|
48
|
+
messagebox.showerror("Error", "Chromium is not installed. Execute 'rfbrowser init chromium'.", master=window)
|
|
49
|
+
else:
|
|
50
|
+
incognito_flag = ["-incognito"] if incognito else []
|
|
51
|
+
chrome_exe = chromium_dir / "chrome-win" / "chrome.exe"
|
|
52
|
+
Popen([chrome_exe, f"--remote-debugging-port={remote_debugging_port}", "--test-type"] + incognito_flag)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TrayIcon:
|
|
56
|
+
def __init__(self, remote_debugging_port: int):
|
|
57
|
+
chromium_icon = Image.open(Path(realpath(__file__)).parent / "chromium.png")
|
|
58
|
+
|
|
59
|
+
self.remote_debugging_port = remote_debugging_port
|
|
60
|
+
self.icon = Icon(
|
|
61
|
+
name='Browser Tray',
|
|
62
|
+
icon=chromium_icon,
|
|
63
|
+
menu=Menu(
|
|
64
|
+
MenuItem(
|
|
65
|
+
'Open Chromium',
|
|
66
|
+
self.open_chromium,
|
|
67
|
+
default=True
|
|
68
|
+
),
|
|
69
|
+
MenuItem(
|
|
70
|
+
'Open Chromium Incognito',
|
|
71
|
+
self.open_chromium_incognito,
|
|
72
|
+
),
|
|
73
|
+
MenuItem(
|
|
74
|
+
'Exit',
|
|
75
|
+
self.exit
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
def exit(self):
|
|
81
|
+
self.icon.stop()
|
|
82
|
+
|
|
83
|
+
def open_chromium(self):
|
|
84
|
+
start_chromium(self.remote_debugging_port, False)
|
|
85
|
+
|
|
86
|
+
def open_chromium_incognito(self):
|
|
87
|
+
start_chromium(self.remote_debugging_port, True)
|
|
88
|
+
|
|
89
|
+
def run(self):
|
|
90
|
+
cmd = "browser-tray.exe"
|
|
91
|
+
if is_running(cmd):
|
|
92
|
+
print(f"{cmd} is already running")
|
|
93
|
+
sys.exit(1)
|
|
94
|
+
|
|
95
|
+
self.icon.run()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def is_running(cmd: str) -> bool:
|
|
99
|
+
process_list = subprocess.check_output(
|
|
100
|
+
# Set the character page to 65001 = UTF-8
|
|
101
|
+
f'chcp 65001 | TASKLIST /FI "IMAGENAME eq {cmd}"', shell=True
|
|
102
|
+
).decode('utf-8').splitlines()
|
|
103
|
+
instances = [
|
|
104
|
+
process
|
|
105
|
+
for process in process_list
|
|
106
|
+
if process.startswith(cmd)
|
|
107
|
+
]
|
|
108
|
+
return len(instances) > 1
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def run():
|
|
112
|
+
playwright_process_port, remote_debugging_port = cmdline_args.get_ports()
|
|
113
|
+
tray_icon = TrayIcon(remote_debugging_port)
|
|
114
|
+
tray_icon.run()
|
|
@@ -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", "timeout=2s")
|
|
10
|
-
self.connect()
|
|
11
|
-
|
|
12
|
-
def connect(self):
|
|
13
|
-
BuiltIn().run_keyword("Connect To Browser", "http://localhost:1234", "chromium", "use_cdp=True")
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import http.client
|
|
3
|
-
import os
|
|
4
|
-
import site
|
|
5
|
-
import socket
|
|
6
|
-
import subprocess
|
|
7
|
-
import sys
|
|
8
|
-
import time
|
|
9
|
-
import tkinter as tk
|
|
10
|
-
from os.path import realpath
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from subprocess import Popen
|
|
13
|
-
from tkinter import messagebox
|
|
14
|
-
from typing import List, Tuple
|
|
15
|
-
|
|
16
|
-
from PIL import Image
|
|
17
|
-
from pystray import Icon, Menu, MenuItem
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
REMOTE_DEBUGGING_PORT = 1234
|
|
21
|
-
PLAYWRIGHT_PROCESS_PORT= 4711
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
_, site_packages = site.getsitepackages()
|
|
25
|
-
browser_wrapper = Path(site_packages) / "Browser" / "wrapper"
|
|
26
|
-
index_js = browser_wrapper / "index.js"
|
|
27
|
-
node_modules = browser_wrapper / "node_modules"
|
|
28
|
-
playwright_core = node_modules / "playwright-core"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def find_chromium(path: Path) -> List[Path]:
|
|
32
|
-
return [
|
|
33
|
-
Path(file.path)
|
|
34
|
-
for file in os.scandir(path)
|
|
35
|
-
if file.is_dir() and file.name.startswith("chromium")
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def playwright_is_initialized():
|
|
40
|
-
return node_modules.is_dir() and playwright_core.is_dir()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def get_chromium_dir(node_modules: Path):
|
|
44
|
-
local_browsers = playwright_core / ".local-browsers"
|
|
45
|
-
|
|
46
|
-
if not (node_modules.is_dir() and local_browsers.is_dir() and find_chromium(local_browsers)):
|
|
47
|
-
return None
|
|
48
|
-
|
|
49
|
-
return find_chromium(local_browsers)[0]
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def start_playwright(playwright_process_port: int) -> Popen:
|
|
53
|
-
return Popen(['node', index_js, str(playwright_process_port)])
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class TrayIcon:
|
|
57
|
-
def __init__(self, playwright_process_port: int, remote_debugging_port: int, timeout=0):
|
|
58
|
-
chromium_icon = Image.open(Path(realpath(__file__)).parent / "chromium.png")
|
|
59
|
-
|
|
60
|
-
playwright_process = start_playwright(playwright_process_port)
|
|
61
|
-
time.sleep(2)
|
|
62
|
-
return_code = playwright_process.poll()
|
|
63
|
-
|
|
64
|
-
if return_code:
|
|
65
|
-
sys.exit(return_code)
|
|
66
|
-
|
|
67
|
-
if timeout:
|
|
68
|
-
time.sleep(timeout)
|
|
69
|
-
playwright_process.kill()
|
|
70
|
-
sys.exit(0)
|
|
71
|
-
|
|
72
|
-
self.processes = [playwright_process]
|
|
73
|
-
self.remote_debugging_port = remote_debugging_port
|
|
74
|
-
self.icon = Icon(
|
|
75
|
-
name='Browser Tray',
|
|
76
|
-
icon=chromium_icon,
|
|
77
|
-
menu=Menu(
|
|
78
|
-
MenuItem(
|
|
79
|
-
'Open Chromium',
|
|
80
|
-
self.open_chromium,
|
|
81
|
-
default=True
|
|
82
|
-
),
|
|
83
|
-
MenuItem(
|
|
84
|
-
'Open Chromium Incognito',
|
|
85
|
-
self.open_chromium_incognito,
|
|
86
|
-
),
|
|
87
|
-
MenuItem(
|
|
88
|
-
'Exit',
|
|
89
|
-
self.exit
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
def exit(self):
|
|
95
|
-
for proc in self.processes:
|
|
96
|
-
proc.terminate()
|
|
97
|
-
|
|
98
|
-
self.icon.stop()
|
|
99
|
-
|
|
100
|
-
def open_chromium(self):
|
|
101
|
-
self.start_chromium(self.remote_debugging_port, False)
|
|
102
|
-
|
|
103
|
-
def open_chromium_incognito(self):
|
|
104
|
-
self.start_chromium(self.remote_debugging_port, True)
|
|
105
|
-
|
|
106
|
-
def run(self):
|
|
107
|
-
self.icon.run()
|
|
108
|
-
|
|
109
|
-
def start_chromium(self, remote_debugging_port: int, incognito: bool):
|
|
110
|
-
chromium_dir = get_chromium_dir(node_modules)
|
|
111
|
-
|
|
112
|
-
if not chromium_dir:
|
|
113
|
-
window = tk.Tk()
|
|
114
|
-
window.withdraw()
|
|
115
|
-
messagebox.showerror("Error", "Chromium is not installed. Execute 'rfbrowser init chromium'.", master=window)
|
|
116
|
-
else:
|
|
117
|
-
incognito_flag = ["-incognito"] if incognito else []
|
|
118
|
-
chrome_exe = chromium_dir / "chrome-win" / "chrome.exe"
|
|
119
|
-
chromium = Popen([chrome_exe, f"--remote-debugging-port={remote_debugging_port}", "--test-type"] + incognito_flag)
|
|
120
|
-
time.sleep(2)
|
|
121
|
-
self.processes.append(chromium)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def is_running(cmd: str) -> bool:
|
|
125
|
-
process_list = subprocess.check_output(
|
|
126
|
-
# Set the character page to 65001 = UTF-8
|
|
127
|
-
f'chcp 65001 | TASKLIST /FI "IMAGENAME eq {cmd}"', shell=True
|
|
128
|
-
).decode('utf-8').splitlines()
|
|
129
|
-
instances = [
|
|
130
|
-
process
|
|
131
|
-
for process in process_list
|
|
132
|
-
if process.startswith(cmd) and os.getlogin().lower() in process.lower()
|
|
133
|
-
]
|
|
134
|
-
return len(instances) > 1
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def get_ports() -> Tuple[int, int]:
|
|
138
|
-
MAX_PORT = 2**16
|
|
139
|
-
|
|
140
|
-
arg_parser = argparse.ArgumentParser(add_help=True)
|
|
141
|
-
arg_parser.add_argument("--pw-port", default=PLAYWRIGHT_PROCESS_PORT, type=int, help=f"Playwright process port (default: {PLAYWRIGHT_PROCESS_PORT})")
|
|
142
|
-
arg_parser.add_argument("--cdp-port", default=REMOTE_DEBUGGING_PORT, type=int, help=f"Chromium debugging port (default: {REMOTE_DEBUGGING_PORT})")
|
|
143
|
-
args = arg_parser.parse_args()
|
|
144
|
-
playwright_process_port = args.pw_port
|
|
145
|
-
remote_debugging_port = args.cdp_port
|
|
146
|
-
|
|
147
|
-
if playwright_process_port > MAX_PORT or remote_debugging_port > MAX_PORT:
|
|
148
|
-
raise ValueError(f"Port numbers cannot be larger than {MAX_PORT}")
|
|
149
|
-
|
|
150
|
-
return (playwright_process_port, remote_debugging_port)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def run():
|
|
154
|
-
cmd = "browser-tray.exe"
|
|
155
|
-
if is_running(cmd):
|
|
156
|
-
print(f"{cmd} is already running")
|
|
157
|
-
sys.exit(1)
|
|
158
|
-
|
|
159
|
-
playwright_process_port, remote_debugging_port = get_ports()
|
|
160
|
-
|
|
161
|
-
if not playwright_is_initialized():
|
|
162
|
-
print(
|
|
163
|
-
"Playwright has not been initialized.\n" +
|
|
164
|
-
"In order to use Chromium execute 'rfbrowser init chromium'.\n" +
|
|
165
|
-
"If you want to use the Microsoft Edge installed on your system execute 'rfbrowser init --skip-browsers'"
|
|
166
|
-
)
|
|
167
|
-
sys.exit(1)
|
|
168
|
-
|
|
169
|
-
try:
|
|
170
|
-
http.client.HTTPConnection('127.0.0.1', playwright_process_port, timeout=1).connect()
|
|
171
|
-
print("The port 4711 is already in use. Either browser-tray is already running or another process is using the port.\n" +
|
|
172
|
-
"To start the Playwright wrapper on another port execute `browser-tray --pw-port PORT`")
|
|
173
|
-
sys.exit(1)
|
|
174
|
-
except socket.timeout:
|
|
175
|
-
tray_icon = TrayIcon(playwright_process_port, remote_debugging_port)
|
|
176
|
-
tray_icon.run()
|
{robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/__init__.py
RENAMED
|
File without changes
|
{robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/__main__.py
RENAMED
|
File without changes
|
{robotframework_browser_tray-1.6.0 → robotframework_browser_tray-1.7.0}/src/BrowserTray/chromium.png
RENAMED
|
File without changes
|