-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocument_generator.py
More file actions
360 lines (284 loc) · 12.7 KB
/
document_generator.py
File metadata and controls
360 lines (284 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
"""
Document Generator for creating BDD scenario documents in various formats
"""
import os
import json
import markdown
from datetime import datetime
from typing import Dict, Any, Optional
from reportlab.lib.pagesizes import letter, A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib import colors
class DocumentGenerator:
"""Generator for creating BDD documents in multiple formats"""
def __init__(self, output_dir: str = "output"):
"""
Initialize document generator
Args:
output_dir: Directory to save generated documents
"""
self.output_dir = output_dir
self.ensure_output_dir()
def ensure_output_dir(self):
"""Create output directory if it doesn't exist"""
if not os.path.exists(self.output_dir):
os.makedirs(self.output_dir)
def save_json_data(self, data: Dict[str, Any], filename: str) -> str:
"""
Save data as JSON file
Args:
data: Data to save
filename: Output filename (without extension)
Returns:
Path to saved file
"""
filepath = os.path.join(self.output_dir, f"{filename}.json")
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
return filepath
def generate_markdown_document(self, bdd_scenarios: str, figma_data: Dict[str, Any],
filename: str = "bdd_scenarios") -> str:
"""
Generate BDD document in Markdown format
Args:
bdd_scenarios: Generated BDD scenarios
figma_data: Original Figma design data
filename: Output filename (without extension)
Returns:
Path to saved markdown file
"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
markdown_content = f"""# BDD Test Scenarios
**Generated on:** {timestamp}
**Source:** Figma Design - {figma_data.get('file_name', 'Unknown')}
## Project Overview
This document contains Behavior Driven Development (BDD) test scenarios generated from Figma design specifications. The scenarios are written in Gherkin format and can be used with testing frameworks like Cucumber, SpecFlow, or Behave.
## Design Summary
- **File Name:** {figma_data.get('file_name', 'Unknown')}
- **Pages:** {len(figma_data.get('pages', []))}
- **Components:** {len(figma_data.get('components', []))}
- **Interactive Elements:** {len(figma_data.get('interactive_elements', []))}
## Generated BDD Scenarios
{bdd_scenarios}
## Design Data Reference
The following design elements were analyzed to generate these scenarios:
### Pages and Frames
"""
# Add page information
for page in figma_data.get('pages', []):
markdown_content += f"\n#### {page.get('name', 'Unnamed Page')}\n"
for frame in page.get('frames', []):
markdown_content += f"- **{frame.get('name', 'Unnamed Frame')}:** {frame.get('type', 'Unknown Type')}\n"
markdown_content += "\n### Key UI Elements\n"
# Add element information
for page in figma_data.get('pages', []):
for frame in page.get('frames', []):
for element in frame.get('elements', []):
if element.get('type') in ['TEXT', 'COMPONENT', 'INSTANCE']:
markdown_content += f"- **{element.get('name', 'Unnamed Element')}** ({element.get('type')})\n"
markdown_content += f"""
## Usage Instructions
1. Import these scenarios into your preferred BDD testing framework
2. Implement step definitions for each Given/When/Then step
3. Configure your test environment to match the design specifications
4. Execute the scenarios as part of your testing pipeline
## Notes
- These scenarios are generated based on UI design analysis
- Additional business logic scenarios may need to be added manually
- Verify that all interactive elements have corresponding test steps
- Update scenarios as the design evolves
---
*Generated by FigmaToBDD Tool*
"""
filepath = os.path.join(self.output_dir, f"{filename}.md")
with open(filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
return filepath
def generate_pdf_document(self, bdd_scenarios: str, figma_data: Dict[str, Any],
filename: str = "bdd_scenarios") -> str:
"""
Generate BDD document in PDF format
Args:
bdd_scenarios: Generated BDD scenarios
figma_data: Original Figma design data
filename: Output filename (without extension)
Returns:
Path to saved PDF file
"""
filepath = os.path.join(self.output_dir, f"{filename}.pdf")
# Create PDF document
doc = SimpleDocTemplate(filepath, pagesize=A4)
styles = getSampleStyleSheet()
story = []
# Custom styles
title_style = ParagraphStyle(
'CustomTitle',
parent=styles['Heading1'],
fontSize=24,
spaceAfter=30,
textColor=colors.darkblue
)
heading_style = ParagraphStyle(
'CustomHeading',
parent=styles['Heading2'],
fontSize=16,
spaceAfter=12,
textColor=colors.darkblue
)
# Title
story.append(Paragraph("BDD Test Scenarios", title_style))
story.append(Spacer(1, 20))
# Metadata
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
story.append(Paragraph(f"<b>Generated on:</b> {timestamp}", styles['Normal']))
story.append(Paragraph(f"<b>Source:</b> Figma Design - {figma_data.get('file_name', 'Unknown')}", styles['Normal']))
story.append(Spacer(1, 20))
# Project Overview
story.append(Paragraph("Project Overview", heading_style))
overview_text = """This document contains Behavior Driven Development (BDD) test scenarios
generated from Figma design specifications. The scenarios are written in Gherkin format
and can be used with testing frameworks like Cucumber, SpecFlow, or Behave."""
story.append(Paragraph(overview_text, styles['Normal']))
story.append(Spacer(1, 15))
# Design Summary Table
story.append(Paragraph("Design Summary", heading_style))
summary_data = [
['Property', 'Value'],
['File Name', figma_data.get('file_name', 'Unknown')],
['Pages', str(len(figma_data.get('pages', [])))],
['Components', str(len(figma_data.get('components', [])))],
['Interactive Elements', str(len(figma_data.get('interactive_elements', [])))]
]
summary_table = Table(summary_data)
summary_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 12),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('GRID', (0, 0), (-1, -1), 1, colors.black)
]))
story.append(summary_table)
story.append(Spacer(1, 20))
# BDD Scenarios
story.append(Paragraph("Generated BDD Scenarios", heading_style))
# Split scenarios into paragraphs for better formatting
scenario_lines = bdd_scenarios.split('\n')
for line in scenario_lines:
if line.strip():
if line.startswith('Feature:'):
story.append(Paragraph(line, heading_style))
elif line.startswith('Scenario:') or line.startswith('Scenario Outline:'):
story.append(Spacer(1, 10))
story.append(Paragraph(line, styles['Heading3']))
else:
story.append(Paragraph(line, styles['Normal']))
else:
story.append(Spacer(1, 6))
# Build PDF
doc.build(story)
return filepath
def generate_html_document(self, bdd_scenarios: str, figma_data: Dict[str, Any],
filename: str = "bdd_scenarios") -> str:
"""
Generate BDD document in HTML format
Args:
bdd_scenarios: Generated BDD scenarios
figma_data: Original Figma design data
filename: Output filename (without extension)
Returns:
Path to saved HTML file
"""
# First create markdown content
md_content = self._create_markdown_content(bdd_scenarios, figma_data)
# Convert to HTML
html_content = markdown.markdown(md_content, extensions=['tables', 'toc'])
# Wrap in full HTML document
full_html = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BDD Test Scenarios - {figma_data.get('file_name', 'Unknown')}</title>
<style>
body {{
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}}
h1, h2, h3 {{ color: #2c3e50; }}
h1 {{ border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
h2 {{ border-bottom: 1px solid #bdc3c7; padding-bottom: 5px; }}
code {{ background-color: #f8f9fa; padding: 2px 4px; border-radius: 3px; }}
pre {{ background-color: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; }}
table {{ border-collapse: collapse; width: 100%; margin: 15px 0; }}
th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }}
th {{ background-color: #f2f2f2; font-weight: bold; }}
.scenario {{ background-color: #f9f9f9; padding: 15px; margin: 10px 0; border-left: 4px solid #3498db; }}
.feature {{ background-color: #e8f4fd; padding: 15px; margin: 20px 0; border-radius: 5px; }}
</style>
</head>
<body>
{html_content}
</body>
</html>"""
filepath = os.path.join(self.output_dir, f"{filename}.html")
with open(filepath, 'w', encoding='utf-8') as f:
f.write(full_html)
return filepath
def _create_markdown_content(self, bdd_scenarios: str, figma_data: Dict[str, Any]) -> str:
"""Create markdown content for HTML conversion"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return f"""# BDD Test Scenarios
**Generated on:** {timestamp}
**Source:** Figma Design - {figma_data.get('file_name', 'Unknown')}
## Project Overview
This document contains Behavior Driven Development (BDD) test scenarios generated from Figma design specifications.
| Property | Value |
|----------|-------|
| File Name | {figma_data.get('file_name', 'Unknown')} |
| Pages | {len(figma_data.get('pages', []))} |
| Components | {len(figma_data.get('components', []))} |
| Interactive Elements | {len(figma_data.get('interactive_elements', []))} |
## Generated BDD Scenarios
{bdd_scenarios}
---
*Generated by FigmaToBDD Tool*
"""
def save_figma_data(self, figma_data: Dict[str, Any], filename: str = "figma_design_data") -> str:
"""
Save Figma design data as JSON
Args:
figma_data: Figma design data
filename: Output filename
Returns:
Path to saved file
"""
return self.save_json_data(figma_data, filename)
def generate_all_formats(self, bdd_scenarios: str, figma_data: Dict[str, Any],
base_filename: str = "bdd_scenarios") -> Dict[str, str]:
"""
Generate documents in all supported formats
Args:
bdd_scenarios: Generated BDD scenarios
figma_data: Original Figma design data
base_filename: Base filename for all documents
Returns:
Dictionary with format names and file paths
"""
generated_files = {}
try:
generated_files['json'] = self.save_figma_data(figma_data, f"{base_filename}_data")
generated_files['markdown'] = self.generate_markdown_document(bdd_scenarios, figma_data, base_filename)
generated_files['html'] = self.generate_html_document(bdd_scenarios, figma_data, base_filename)
generated_files['pdf'] = self.generate_pdf_document(bdd_scenarios, figma_data, base_filename)
except Exception as e:
print(f"Warning: Some formats may not have been generated due to: {str(e)}")
return generated_files