dina1 commited on
Commit
ace9916
Β·
verified Β·
1 Parent(s): c2862a2

Update playwright_model.py

Browse files
Files changed (1) hide show
  1. playwright_model.py +54 -58
playwright_model.py CHANGED
@@ -17,40 +17,70 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
17
  print(f"Opening page: {public_url}")
18
  await page.goto(public_url, wait_until="load")
19
 
20
- # βœ… Sidebar stability detector (same as before)
21
  async def wait_for_sidebar_stable():
22
  try:
23
  await page.evaluate("""
24
  (async () => {
25
  const sidebar = document.querySelector('aside, .sidebar, nav');
26
  if (!sidebar) return;
27
- function getLeft() {
 
28
  const rect = sidebar.getBoundingClientRect();
29
- return rect.left;
30
  }
 
31
  let stableCount = 0;
32
- let lastLeft = getLeft();
 
33
  await new Promise((resolve) => {
34
  const check = setInterval(() => {
35
- const currentLeft = getLeft();
36
- if (Math.abs(currentLeft - lastLeft) < 1) {
 
 
 
37
  stableCount++;
38
- if (stableCount >= 5) { // stable for ~750ms
39
  clearInterval(check);
40
- setTimeout(resolve, 500); // small safety delay
41
  }
42
  } else {
43
  stableCount = 0;
44
- lastLeft = currentLeft;
45
  }
46
- }, 150);
47
  });
48
  })();
49
  """)
50
  except Exception as e:
51
  print(f"[WARN] Sidebar stability check failed: {e}")
52
 
53
- # βœ… JS logic to map workflows + subscreens
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  js_logic = """
55
  (function(){
56
  const menus=[...document.querySelectorAll('.menu-item')];
@@ -70,6 +100,7 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
70
  window.__visitedWorkflows=[];
71
  window.__currentIndex=0;
72
  window.__done=false;
 
73
  window.__getSubScreens = function(screen){
74
  const tabs=[...screen.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab], .sub-tab, .tab-item')];
75
  const list=[];
@@ -79,6 +110,7 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
79
  }
80
  return list;
81
  };
 
82
  window.__captureNext=async function(){
83
  if(window.__done) return false;
84
  if(window.__currentIndex>=window.__ordered.length){window.__done=true;return false;}
@@ -100,6 +132,7 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
100
  const subs = window.__getSubScreens(screen);
101
  return {screenName:wfName, subScreens:subs};
102
  };
 
103
  window.__clickSubScreen = async function(name){
104
  const tabs=[...document.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab], .sub-tab, .tab-item')];
105
  const t=tabs.find(x=>x.textContent.trim()===name);
@@ -114,41 +147,7 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
114
  screenshots = []
115
  index = 0
116
 
117
- # βœ… Helper: Expand layout (simulate your frontend JS logic)
118
- async def expand_layout_for_capture():
119
- await page.evaluate("""
120
- const body = document.body;
121
- const html = document.documentElement;
122
- body.dataset.originalOverflow = body.style.overflow;
123
- html.dataset.originalWidth = html.style.width;
124
- html.dataset.originalHeight = html.style.height;
125
-
126
- const fullWidth = Math.max(
127
- body.scrollWidth,
128
- html.scrollWidth,
129
- document.documentElement.offsetWidth
130
- );
131
- const fullHeight = Math.max(
132
- body.scrollHeight,
133
- html.scrollHeight,
134
- document.documentElement.offsetHeight
135
- );
136
-
137
- body.style.overflow = 'visible';
138
- html.style.width = fullWidth + 'px';
139
- html.style.height = fullHeight + 'px';
140
- """)
141
-
142
- async def restore_layout_after_capture():
143
- await page.evaluate("""
144
- const body = document.body;
145
- const html = document.documentElement;
146
- if (body.dataset.originalOverflow) body.style.overflow = body.dataset.originalOverflow;
147
- if (html.dataset.originalWidth) html.style.width = html.dataset.originalWidth;
148
- if (html.dataset.originalHeight) html.style.height = html.dataset.originalHeight;
149
- """)
150
-
151
- # βœ… Capture all workflows and subscreens
152
  while True:
153
  result = await page.evaluate("window.__captureNext()")
154
  if not result:
@@ -159,7 +158,7 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
159
  screenshot_path = os.path.join(OUTPUT_DIR, f"{screen_name}.png")
160
  print(f"πŸ“Έ Capturing main screen: {screen_name}")
161
 
162
- # Update page title dynamically
163
  await page.evaluate(
164
  """(name) => {
165
  const titleEl = document.querySelector('.page-title, .header-title, main h2');
@@ -169,17 +168,15 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
169
  screen_name
170
  )
171
 
 
172
  await wait_for_sidebar_stable()
173
- await asyncio.sleep(1.2)
 
174
 
175
- # βœ… NEW: Expand layout for correct sidebar alignment
176
- await expand_layout_for_capture()
177
  await page.screenshot(path=screenshot_path, full_page=True)
178
- await restore_layout_after_capture()
179
-
180
  screenshots.append(screenshot_path)
181
 
182
- # βœ… Capture sub-screens dynamically
183
  first_active_skipped = False
184
  for sub in sub_screens:
185
  is_active = await page.evaluate(
@@ -199,7 +196,10 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
199
 
200
  print(f" ↳ Capturing sub-screen: {sub}")
201
  await page.evaluate(f"window.__clickSubScreen('{sub}')")
 
 
202
  await wait_for_sidebar_stable()
 
203
  await asyncio.sleep(1.0)
204
 
205
  sub_name_clean = sub.replace(" ", "_").lower()
@@ -215,18 +215,14 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
215
  [screen_name, sub]
216
  )
217
 
218
- # βœ… NEW: Apply same layout-expansion logic
219
- await expand_layout_for_capture()
220
  await page.screenshot(path=sub_path, full_page=True)
221
- await restore_layout_after_capture()
222
-
223
  screenshots.append(sub_path)
224
 
225
  index += 1
226
 
227
  await browser.close()
228
 
229
- # βœ… Combine screenshots into PDF
230
  if not screenshots:
231
  raise RuntimeError("No screenshots captured β€” check if .screen elements exist!")
232
 
 
17
  print(f"Opening page: {public_url}")
18
  await page.goto(public_url, wait_until="load")
19
 
20
+ # βœ… Improved sidebar + layout stability detector
21
  async def wait_for_sidebar_stable():
22
  try:
23
  await page.evaluate("""
24
  (async () => {
25
  const sidebar = document.querySelector('aside, .sidebar, nav');
26
  if (!sidebar) return;
27
+
28
+ function getMetrics() {
29
  const rect = sidebar.getBoundingClientRect();
30
+ return { left: rect.left, width: rect.width };
31
  }
32
+
33
  let stableCount = 0;
34
+ let last = getMetrics();
35
+
36
  await new Promise((resolve) => {
37
  const check = setInterval(() => {
38
+ const now = getMetrics();
39
+ if (
40
+ Math.abs(now.left - last.left) < 0.5 &&
41
+ Math.abs(now.width - last.width) < 0.5
42
+ ) {
43
  stableCount++;
44
+ if (stableCount >= 5) {
45
  clearInterval(check);
46
+ setTimeout(resolve, 400); // safety delay after motion stops
47
  }
48
  } else {
49
  stableCount = 0;
50
+ last = now;
51
  }
52
+ }, 120);
53
  });
54
  })();
55
  """)
56
  except Exception as e:
57
  print(f"[WARN] Sidebar stability check failed: {e}")
58
 
59
+ # βœ… Wait for full layout to settle (scroll + reflows)
60
+ async def wait_for_layout_stable():
61
+ await page.evaluate("""
62
+ (async () => {
63
+ let stableCount = 0;
64
+ let lastHeight = document.body.scrollHeight;
65
+ await new Promise((resolve) => {
66
+ const check = setInterval(() => {
67
+ const current = document.body.scrollHeight;
68
+ if (Math.abs(current - lastHeight) < 1) {
69
+ stableCount++;
70
+ if (stableCount >= 5) {
71
+ clearInterval(check);
72
+ setTimeout(resolve, 300);
73
+ }
74
+ } else {
75
+ stableCount = 0;
76
+ lastHeight = current;
77
+ }
78
+ }, 100);
79
+ });
80
+ })();
81
+ """)
82
+
83
+ # βœ… Inject workflow traversal + sub-screen logic
84
  js_logic = """
85
  (function(){
86
  const menus=[...document.querySelectorAll('.menu-item')];
 
100
  window.__visitedWorkflows=[];
101
  window.__currentIndex=0;
102
  window.__done=false;
103
+
104
  window.__getSubScreens = function(screen){
105
  const tabs=[...screen.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab], .sub-tab, .tab-item')];
106
  const list=[];
 
110
  }
111
  return list;
112
  };
113
+
114
  window.__captureNext=async function(){
115
  if(window.__done) return false;
116
  if(window.__currentIndex>=window.__ordered.length){window.__done=true;return false;}
 
132
  const subs = window.__getSubScreens(screen);
133
  return {screenName:wfName, subScreens:subs};
134
  };
135
+
136
  window.__clickSubScreen = async function(name){
137
  const tabs=[...document.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab], .sub-tab, .tab-item')];
138
  const t=tabs.find(x=>x.textContent.trim()===name);
 
147
  screenshots = []
148
  index = 0
149
 
150
+ # βœ… Loop through each workflow
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  while True:
152
  result = await page.evaluate("window.__captureNext()")
153
  if not result:
 
158
  screenshot_path = os.path.join(OUTPUT_DIR, f"{screen_name}.png")
159
  print(f"πŸ“Έ Capturing main screen: {screen_name}")
160
 
161
+ # Update visible + browser tab title dynamically
162
  await page.evaluate(
163
  """(name) => {
164
  const titleEl = document.querySelector('.page-title, .header-title, main h2');
 
168
  screen_name
169
  )
170
 
171
+ # βœ… Wait for sidebar and layout to fully stabilize
172
  await wait_for_sidebar_stable()
173
+ await wait_for_layout_stable()
174
+ await asyncio.sleep(1.0)
175
 
 
 
176
  await page.screenshot(path=screenshot_path, full_page=True)
 
 
177
  screenshots.append(screenshot_path)
178
 
179
+ # βœ… Capture sub-screens dynamically (skip first active one)
180
  first_active_skipped = False
181
  for sub in sub_screens:
182
  is_active = await page.evaluate(
 
196
 
197
  print(f" ↳ Capturing sub-screen: {sub}")
198
  await page.evaluate(f"window.__clickSubScreen('{sub}')")
199
+
200
+ # βœ… Wait until sidebar + layout stable again
201
  await wait_for_sidebar_stable()
202
+ await wait_for_layout_stable()
203
  await asyncio.sleep(1.0)
204
 
205
  sub_name_clean = sub.replace(" ", "_").lower()
 
215
  [screen_name, sub]
216
  )
217
 
 
 
218
  await page.screenshot(path=sub_path, full_page=True)
 
 
219
  screenshots.append(sub_path)
220
 
221
  index += 1
222
 
223
  await browser.close()
224
 
225
+ # βœ… Combine all screenshots into PDF
226
  if not screenshots:
227
  raise RuntimeError("No screenshots captured β€” check if .screen elements exist!")
228