dina1 commited on
Commit
ee6b40d
Β·
verified Β·
1 Parent(s): f49d63a

Update playwright_model.py

Browse files
Files changed (1) hide show
  1. playwright_model.py +61 -22
playwright_model.py CHANGED
@@ -13,16 +13,17 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
13
  async with async_playwright() as p:
14
  browser = await p.chromium.launch(headless=True)
15
  page = await browser.new_page()
16
- print(f"Opening page: {public_url}")
17
  await page.goto(public_url, wait_until="load")
18
 
19
- # βœ… Inject workflow traversal logic (copied from your frontend)
20
  js_logic = """
21
  (function(){
22
  const menus=[...document.querySelectorAll('.menu-item')];
23
  const screens=[...document.querySelectorAll('.screen')];
24
  window.__ordered=[];
25
  const seen=new Set();
 
26
  for(const m of menus){
27
  let id=m.dataset.screen||m.dataset.target;
28
  if(!id){
@@ -33,65 +34,103 @@ async def capture_workflows(public_url: str, pdf_filename: str = "workflow_scree
33
  if(s && !seen.has(s)){seen.add(s);window.__ordered.push({menu:m,screen:s});}
34
  }
35
  for(const s of screens) if(!seen.has(s)) window.__ordered.push({menu:null,screen:s});
 
36
  window.__visitedWorkflows=[];
37
  window.__currentIndex=0;
38
  window.__done=false;
 
 
 
 
 
 
 
 
 
 
 
39
  window.__captureNext=async function(){
40
  if(window.__done) return false;
41
  if(window.__currentIndex>=window.__ordered.length){window.__done=true;return false;}
42
  const pair=window.__ordered[window.__currentIndex];
43
  const {menu,screen}=pair;
44
  if(!screen){window.__done=true;return false;}
 
45
  const wfName=screen.id || screen.getAttribute('data-name') || ('screen_'+window.__currentIndex);
46
- if(window.__visitedWorkflows.includes(wfName)){window.__done=true;return false;}
 
 
 
 
47
  window.__visitedWorkflows.push(wfName);
48
  document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active'));
49
  document.querySelectorAll('.menu-item').forEach(m=>m.classList.remove('active'));
50
  screen.classList.add('active');
51
  if(menu) menu.classList.add('active');
52
  screen.scrollIntoView({behavior:'smooth',block:'center'});
 
 
 
 
 
53
  window.__currentIndex++;
54
- return {screenName:wfName};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  };
56
  })();
57
  """
 
58
  await page.evaluate(js_logic)
59
  await asyncio.sleep(1)
60
 
61
  screenshots = []
62
  index = 0
63
 
64
- # βœ… Loop through each workflow
65
  while True:
66
  result = await page.evaluate("window.__captureNext()")
67
  if not result:
68
  break
69
 
70
  screen_name = result.get("screenName", f"screen_{index}")
 
 
 
71
  screenshot_path = os.path.join(OUTPUT_DIR, f"{screen_name}.png")
72
- print(f"πŸ“Έ Capturing {screen_name} -> {screenshot_path}")
73
-
74
- # βœ… Dynamically update visible and tab title before screenshot
75
- await page.evaluate(
76
- """(name) => {
77
- // Update visible title text
78
- const titleEl = document.querySelector('.page-title, .header-title, main h2');
79
- if (titleEl) titleEl.textContent = name;
80
-
81
- // Update browser tab title
82
- document.title = name;
83
- }""",
84
- screen_name
85
- )
86
-
87
- await asyncio.sleep(1.2) # wait for animations/UI updates
88
  await page.screenshot(path=screenshot_path, full_page=True)
89
  screenshots.append(screenshot_path)
 
 
 
 
 
 
 
 
 
 
90
  index += 1
91
 
92
  await browser.close()
93
 
94
- # βœ… Combine all screenshots into a single PDF
95
  if not screenshots:
96
  raise RuntimeError("No screenshots captured β€” check if .screen elements exist!")
97
 
 
13
  async with async_playwright() as p:
14
  browser = await p.chromium.launch(headless=True)
15
  page = await browser.new_page()
16
+ print(f"🌐 Opening page: {public_url}")
17
  await page.goto(public_url, wait_until="load")
18
 
19
+ # βœ… Inject enhanced logic to capture main and sub screens dynamically
20
  js_logic = """
21
  (function(){
22
  const menus=[...document.querySelectorAll('.menu-item')];
23
  const screens=[...document.querySelectorAll('.screen')];
24
  window.__ordered=[];
25
  const seen=new Set();
26
+
27
  for(const m of menus){
28
  let id=m.dataset.screen||m.dataset.target;
29
  if(!id){
 
34
  if(s && !seen.has(s)){seen.add(s);window.__ordered.push({menu:m,screen:s});}
35
  }
36
  for(const s of screens) if(!seen.has(s)) window.__ordered.push({menu:null,screen:s});
37
+
38
  window.__visitedWorkflows=[];
39
  window.__currentIndex=0;
40
  window.__done=false;
41
+
42
+ async function getSubScreens(screen){
43
+ const tabs=[...screen.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab]')];
44
+ const results=[];
45
+ for(const t of tabs){
46
+ const subName=t.textContent?.trim().replace(/\\s+/g,'-').toLowerCase();
47
+ if(subName) results.push({tab:t, name:subName});
48
+ }
49
+ return results;
50
+ }
51
+
52
  window.__captureNext=async function(){
53
  if(window.__done) return false;
54
  if(window.__currentIndex>=window.__ordered.length){window.__done=true;return false;}
55
  const pair=window.__ordered[window.__currentIndex];
56
  const {menu,screen}=pair;
57
  if(!screen){window.__done=true;return false;}
58
+
59
  const wfName=screen.id || screen.getAttribute('data-name') || ('screen_'+window.__currentIndex);
60
+ if(window.__visitedWorkflows.includes(wfName)){
61
+ window.__currentIndex++;
62
+ return window.__captureNext();
63
+ }
64
+
65
  window.__visitedWorkflows.push(wfName);
66
  document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active'));
67
  document.querySelectorAll('.menu-item').forEach(m=>m.classList.remove('active'));
68
  screen.classList.add('active');
69
  if(menu) menu.classList.add('active');
70
  screen.scrollIntoView({behavior:'smooth',block:'center'});
71
+
72
+ const mainTitle = screen.querySelector('.page-title, .header-title, h2')?.textContent?.trim() || wfName;
73
+ document.title = mainTitle;
74
+
75
+ const subs = await getSubScreens(screen);
76
  window.__currentIndex++;
77
+ return {screenName: wfName, subScreens: subs.map(x=>x.name)};
78
+ };
79
+
80
+ window.__clickSubScreen = async function(mainName, subName){
81
+ const screen = document.getElementById(mainName);
82
+ if(!screen) return false;
83
+ const tab=[...screen.querySelectorAll('.tab, .nav-link, [role="tab"], [data-tab]')]
84
+ .find(t=>t.textContent.trim().toLowerCase().includes(subName));
85
+ if(tab){
86
+ tab.click();
87
+ await new Promise(r=>setTimeout(r,700));
88
+ const title = screen.querySelector('.page-title, .header-title, h2')?.textContent?.trim() || mainName;
89
+ document.title = title + ' - ' + subName;
90
+ return true;
91
+ }
92
+ return false;
93
  };
94
  })();
95
  """
96
+
97
  await page.evaluate(js_logic)
98
  await asyncio.sleep(1)
99
 
100
  screenshots = []
101
  index = 0
102
 
103
+ # βœ… Loop through main workflows and their sub-screens dynamically
104
  while True:
105
  result = await page.evaluate("window.__captureNext()")
106
  if not result:
107
  break
108
 
109
  screen_name = result.get("screenName", f"screen_{index}")
110
+ sub_screens = result.get("subScreens", [])
111
+
112
+ # Capture main screen
113
  screenshot_path = os.path.join(OUTPUT_DIR, f"{screen_name}.png")
114
+ print(f"πŸ“Έ Capturing main screen: {screen_name}")
115
+
116
+ await asyncio.sleep(1.2)
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  await page.screenshot(path=screenshot_path, full_page=True)
118
  screenshots.append(screenshot_path)
119
+
120
+ # Capture sub-screens/tabs
121
+ for sub in sub_screens:
122
+ print(f" ↳ Capturing sub-screen: {sub}")
123
+ await page.evaluate(f"window.__clickSubScreen('{screen_name}','{sub}')")
124
+ await asyncio.sleep(1.0)
125
+ sub_path = os.path.join(OUTPUT_DIR, f"{screen_name}_{sub}.png")
126
+ await page.screenshot(path=sub_path, full_page=True)
127
+ screenshots.append(sub_path)
128
+
129
  index += 1
130
 
131
  await browser.close()
132
 
133
+ # βœ… Combine all screenshots into PDF
134
  if not screenshots:
135
  raise RuntimeError("No screenshots captured β€” check if .screen elements exist!")
136