robotframework-apex 0.0.0__py3-none-any.whl

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.
@@ -0,0 +1,291 @@
1
+ from pathlib import Path
2
+
3
+
4
+ class ApexGroup():
5
+ def __init__(self, initial_data={}):
6
+ self.properties = {}
7
+ self.properties.update(initial_data)
8
+
9
+ def __setitem__(self, key, value):
10
+ self.properties[key] = value
11
+
12
+ def __getitem__(self, key):
13
+ return self.properties.get(key, None)
14
+
15
+ def get(self, key, default=None):
16
+ return self.properties.get(key, default)
17
+
18
+
19
+ class ApexObject():
20
+ def __init__(self, component_id=None, initial_data={}):
21
+ self.component_id = component_id
22
+ self.properties = {}
23
+ self.properties.update(initial_data)
24
+ self.groups = {}
25
+ self.children = []
26
+
27
+ def __setitem__(self, key, value):
28
+ if isinstance(value, ApexGroup):
29
+ self.groups[key] = value
30
+ elif isinstance(value, ApexObject):
31
+ self.children[key] = value
32
+ else:
33
+ self.properties[key] = value
34
+
35
+ def __getitem__(self, key):
36
+ if key in self.groups:
37
+ return self.groups.get(key, None)
38
+ elif key in self.children:
39
+ return self.children.get(key, None)
40
+ else:
41
+ return self.properties.get(key, None)
42
+
43
+ def add_property(self, key, value):
44
+ self.properties[key] = value
45
+
46
+ def add_group(self, key, value):
47
+ self.groups[key] = value
48
+
49
+ def add_child(self, child):
50
+ self.children.append(child)
51
+
52
+
53
+ class RegionLayout(ApexGroup):
54
+ def __init__(self, initial_data={}):
55
+ super().__init__(initial_data)
56
+
57
+ @property
58
+ def sequence(self):
59
+ return self.properties.get('sequence', None)
60
+
61
+ @property
62
+ def parentRegion(self):
63
+ return self.properties.get('parentRegion', None)
64
+
65
+ class RegionAppearance(ApexGroup):
66
+ def __init__(self, initial_data={}):
67
+ super().__init__(initial_data)
68
+
69
+
70
+
71
+ class Region(ApexObject):
72
+ def __init__(self, component_id=None, initial_data={}):
73
+ super().__init__(component_id, initial_data)
74
+
75
+ @property
76
+ def name(self):
77
+ return self.properties.get('name', None)
78
+
79
+ @property
80
+ def title(self):
81
+ return self.properties.get('title', None)
82
+
83
+ @property
84
+ def type(self):
85
+ return self.properties.get('type', None)
86
+
87
+ @property
88
+ def layout(self):
89
+ return self.groups.get('layout', RegionLayout())
90
+
91
+ @property
92
+ def appearance(self):
93
+ return self.groups.get('appearance', RegionAppearance())
94
+
95
+
96
+ class PageItemLabel(ApexGroup):
97
+ def __init__(self, initial_data={}):
98
+ super().__init__(initial_data)
99
+
100
+ @property
101
+ def label(self):
102
+ return self.properties.get('label', None)
103
+
104
+
105
+ class PageItemSettings(ApexGroup):
106
+ def __init__(self, initial_data={}):
107
+ super().__init__(initial_data)
108
+
109
+
110
+ class PageItemLayout(ApexGroup):
111
+ def __init__(self, initial_data={}):
112
+ super().__init__(initial_data)
113
+
114
+ @property
115
+ def sequence(self):
116
+ return self.properties.get('sequence', None)
117
+
118
+ @property
119
+ def region(self):
120
+ return self.properties.get('region', None)
121
+
122
+
123
+ class PageItemAppearance(ApexGroup):
124
+ def __init__(self, initial_data={}):
125
+ super().__init__(initial_data)
126
+
127
+ class PageItemValidation(ApexGroup):
128
+ def __init__(self, initial_data={}):
129
+ super().__init__(initial_data)
130
+
131
+ class PageItemAdvanced(ApexGroup):
132
+ def __init__(self, initial_data={}):
133
+ super().__init__(initial_data)
134
+
135
+ class PageItemSessionState(ApexGroup):
136
+ def __init__(self, initial_data={}):
137
+ super().__init__(initial_data)
138
+
139
+ class PageItemSecurity(ApexGroup):
140
+ def __init__(self, initial_data={}):
141
+ super().__init__(initial_data)
142
+
143
+
144
+ class PageItem(ApexObject):
145
+ def __init__(self, component_id=None, initial_data={}):
146
+ super().__init__(component_id, initial_data)
147
+
148
+ @property
149
+ def name(self):
150
+ return self.properties.get('name', self.component_id)
151
+
152
+ @property
153
+ def type(self):
154
+ return self.properties.get('type', None)
155
+
156
+
157
+ @property
158
+ def layout(self):
159
+ return self.groups.get('layout', PageItemLayout())
160
+
161
+ @property
162
+ def label(self):
163
+ return self.groups.get('label', PageItemLabel())
164
+
165
+
166
+ class ButtonLayout(ApexGroup):
167
+ def __init__(self, initial_data={}):
168
+ super().__init__(initial_data)
169
+
170
+ @property
171
+ def sequence(self):
172
+ return self.properties.get('sequence', None)
173
+
174
+ @property
175
+ def region(self):
176
+ return self.properties.get('region', None)
177
+
178
+
179
+ class ButtonAppearance(ApexGroup):
180
+ def __init__(self, initial_data={}):
181
+ super().__init__(initial_data)
182
+
183
+ class ButtonBehavior(ApexGroup):
184
+ def __init__(self, initial_data={}):
185
+ super().__init__(initial_data)
186
+
187
+
188
+
189
+ class Button(ApexObject):
190
+ def __init__(self, component_id=None, initial_data={}):
191
+ super().__init__(component_id, initial_data)
192
+
193
+ @property
194
+ def button_name(self):
195
+ return self.properties.get('buttonName', None)
196
+
197
+ @property
198
+ def label(self):
199
+ return self.properties.get('label', None)
200
+
201
+ @property
202
+ def layout(self):
203
+ return self.groups.get('layout', ButtonLayout({}))
204
+
205
+
206
+ class DynamicActionExecution(ApexGroup):
207
+ pass
208
+
209
+ class DynamicActionWhen(ApexGroup):
210
+ pass
211
+
212
+ class DynamicActionClientSideCondition(ApexGroup):
213
+ pass
214
+
215
+ class DynamicAction(ApexObject):
216
+ def __init__(self, component_id=None, initial_data={}):
217
+ super().__init__(component_id, initial_data)
218
+
219
+
220
+ class ActionAffectedElements(ApexGroup):
221
+ pass
222
+
223
+ class Action(ApexObject):
224
+ pass
225
+
226
+ class Process(ApexObject):
227
+ def __init__(self, component_id=None, initial_data={}):
228
+ super().__init__(component_id, initial_data)
229
+
230
+
231
+ class Page(ApexObject):
232
+ def __init__(self, component_id=None, initial_data={}):
233
+ super().__init__(component_id, initial_data)
234
+
235
+ def __str__(self):
236
+ return f"Page<#{self.page} name: {self.name}>"
237
+
238
+ @property
239
+ def page(self):
240
+ return self.properties.get('page', self.component_id)
241
+
242
+ @property
243
+ def name(self):
244
+ return self.properties['name']
245
+
246
+ @property
247
+ def title(self):
248
+ return self.properties['title']
249
+
250
+ @property
251
+ def alias(self):
252
+ return self.properties['alias']
253
+
254
+
255
+ @property
256
+ def appearance(self):
257
+ return self.groups.get('appearance', None)
258
+
259
+ @appearance.setter
260
+ def appearance(self, value):
261
+ self.groups['appearance'] = value
262
+
263
+ @property
264
+ def regions(self):
265
+ return [x for x in self.children if isinstance(x, Region)]
266
+
267
+ @property
268
+ def page_items(self):
269
+ return [x for x in self.children if isinstance(x, PageItem)]
270
+
271
+ @property
272
+ def buttons(self):
273
+ return [x for x in self.children if isinstance(x, Button)]
274
+
275
+ @property
276
+ def dynamic_actions(self):
277
+ return [x for x in self.children if isinstance(x, DynamicAction)]
278
+
279
+ @property
280
+ def processes(self):
281
+ return [x for x in self.children if isinstance(x, Process)]
282
+
283
+
284
+ def get_region(self, reference_or_name):
285
+ regions = [x for x in self.regions if x.component_id==reference_or_name[1:] or x.name==reference_or_name]
286
+ if len(regions) == 1:
287
+ return regions[0]
288
+ elif len(regions) == 0:
289
+ return None
290
+
291
+ return regions
@@ -0,0 +1,189 @@
1
+ from pathlib import Path
2
+ from BrowserApex.cli.apex import *
3
+ import yaml
4
+
5
+ """
6
+ Read YAML and transform to Page object.
7
+
8
+ Property names will be translated to the names used in de APEX Lang spec. (version 26.1)
9
+ """
10
+
11
+ def make_properties(mapper, data, section, object: ApexObject):
12
+ for field_src, field_dest in mapper.items():
13
+ if field_src in data[section]:
14
+ object.add_property(field_dest, data[section][field_src])
15
+
16
+ def make_group(mapper, data):
17
+ d = {}
18
+ for k, v in data.items():
19
+ if k in mapper:
20
+ d[mapper[k]] = v
21
+ else:
22
+ raise AttributeError(f"Unknown property '{k}'")
23
+ return d
24
+
25
+
26
+ def make_region_layout(data):
27
+ f = {
28
+ 'sequence': 'sequence',
29
+ 'parent-region': 'parentRegion',
30
+ 'slot': 'slot',
31
+ 'start-new-layout': 'startNewLayout',
32
+ 'start-new-row': 'startNewRow',
33
+ 'column': 'column',
34
+ 'new-column': 'newColumn',
35
+ 'column-span': 'columnSpan'
36
+ }
37
+ d = make_group(f, data)
38
+ return RegionLayout(d)
39
+
40
+
41
+
42
+ def make_region_appearance(data):
43
+ f = {
44
+ 'icon': 'icon',
45
+ 'template': 'template',
46
+ 'template-options': 'templateOptions',
47
+ 'render-components': 'renderComponents',
48
+ 'css-classes': 'cssClasses',
49
+ }
50
+ d = make_group(f, data)
51
+ return RegionAppearance(d)
52
+
53
+
54
+ def make_region(region):
55
+ r = Region(region['id'])
56
+ make_properties({
57
+ 'name': 'name',
58
+ 'title': 'title',
59
+ 'type': 'type'
60
+ },
61
+ region, 'identification', r
62
+ )
63
+
64
+ if 'layout' in region:
65
+ l = make_region_layout(region['layout'])
66
+ r.add_group('layout', l)
67
+
68
+ if 'appearance' in region:
69
+ a = make_region_appearance(region['appearance'])
70
+ r.add_group('appearance', a)
71
+ return r
72
+
73
+
74
+ def make_page_item_label(data):
75
+ f = {
76
+ 'label': 'label',
77
+ 'alignment': 'alignment',
78
+ }
79
+ d = make_group(f, data)
80
+ return PageItemLabel(d)
81
+
82
+ def make_page_item_layout(data):
83
+ f = {
84
+ 'sequence': 'sequence',
85
+ 'region': 'region',
86
+ 'alignment': 'alignment',
87
+ 'slot': 'slot',
88
+ 'start-new-layout': 'startNewLayout',
89
+ 'start-new-row': 'startNewRow',
90
+ 'column': 'column',
91
+ 'new-column': 'newColumn',
92
+ 'column-span': 'columnSpan',
93
+ 'label-column-span': 'labelColumnSpan',
94
+ }
95
+ d = make_group(f, data)
96
+ return PageItemLayout(d)
97
+
98
+ def make_page_item_appearance(data):
99
+ return {}
100
+
101
+
102
+ def make_page_item(page_item):
103
+ p = PageItem(page_item['id'])
104
+ make_properties({
105
+ 'name': 'name',
106
+ 'type': 'type'
107
+ },
108
+ page_item, 'identification', p
109
+ )
110
+
111
+ if 'label' in page_item:
112
+ l = make_page_item_label(page_item['label'])
113
+ p.add_group('label', l)
114
+
115
+ if 'layout' in page_item:
116
+ l = make_page_item_layout(page_item['layout'])
117
+ p.add_group('layout', l)
118
+
119
+ if 'appearance' in page_item:
120
+ a = make_page_item_appearance(page_item['appearance'])
121
+ p.add_group('appearance', a)
122
+ return p
123
+
124
+
125
+ def make_button_layout(data):
126
+ f = {
127
+ 'sequence': 'sequence',
128
+ 'region': 'region',
129
+ 'slot': 'slot',
130
+ 'column': 'column',
131
+ 'alignment': 'alignment',
132
+ 'new-column': 'newColumn',
133
+ 'column-span': 'columnSpan',
134
+ 'start-new-layout': 'startNewLayout',
135
+ 'start-new-row': 'startNewRow',
136
+
137
+ }
138
+ d = make_group(f, data)
139
+ return ButtonLayout(d)
140
+
141
+ def make_button(data):
142
+ b = Button(data['id'])
143
+ make_properties({
144
+ 'button-name': 'buttonName',
145
+ 'label': 'label'
146
+ }, data, 'identification', b)
147
+
148
+ if 'layout' in data:
149
+ l = make_button_layout(data['layout'])
150
+ b.add_group('layout', l)
151
+
152
+ return b
153
+
154
+
155
+ def parse_yaml_file(fn: Path) -> Page:
156
+
157
+ with open(fn, 'r') as f:
158
+ data = yaml.safe_load(f)
159
+
160
+
161
+
162
+ page = Page(data['id'])
163
+ for field in ['name', 'alias', 'title']:
164
+ if field in data['identification']:
165
+ page.add_property(field, data['identification'][field])
166
+
167
+ for region in data['regions']:
168
+ r = make_region(region)
169
+ page.add_child(r)
170
+
171
+ for page_item in data['page-items']:
172
+ p = make_page_item(page_item)
173
+ page.add_child(p)
174
+
175
+ for button in data['buttons']:
176
+ b = make_button(button)
177
+ page.add_child(b)
178
+
179
+ return page
180
+
181
+
182
+ if __name__ == '__main__': # pragma: no cover
183
+
184
+ page = parse_yaml_file("examples/f300_page_9999.yaml")
185
+
186
+ for r in page.regions:
187
+ print(r.component_id, r.name, r.type)
188
+
189
+ print(page)
@@ -0,0 +1,5 @@
1
+ from . import config
2
+ from . import dump
3
+ from . import show
4
+ from . import parse
5
+ from . import generate
@@ -0,0 +1,19 @@
1
+ import typer
2
+ from rich import print
3
+
4
+
5
+ #from BrowserApex.cli.utils import get_template
6
+ from BrowserApex.cli.main import app
7
+
8
+
9
+ @app.command(name='config')
10
+ def project_config(
11
+ ):
12
+ """
13
+ Show project configuration.
14
+
15
+ Search `rfapex.ini` in the current project.
16
+ Root of project contains `robot.toml` or `pyproject.toml`
17
+ """
18
+
19
+ print("CONFIG")
@@ -0,0 +1,23 @@
1
+ import typer
2
+ from typing import Annotated
3
+ import yaml
4
+ from rich import print
5
+
6
+ #from BrowserApex.cli.utils import get_template
7
+ from BrowserApex.cli.main import app
8
+
9
+ @app.command(name='dump')
10
+ def project_dump(
11
+ pagefile: Annotated[str, typer.Argument(help="The filename of exported page (yaml)")]
12
+ ):
13
+ """
14
+ Dump project raw yaml->dict.
15
+
16
+ """
17
+ data = None
18
+ with open(pagefile, 'r') as f:
19
+ data = yaml.safe_load(f)
20
+ # print(data)
21
+
22
+
23
+ print(data)
@@ -0,0 +1,182 @@
1
+ import typer
2
+ from rich import print
3
+ from typing import Annotated
4
+ import yaml
5
+ from rich import print
6
+ from rich.table import Table
7
+ import sys
8
+ from operator import itemgetter
9
+
10
+ from BrowserApex.cli.main import app
11
+ from BrowserApex.cli.utils import get_config_path, get_config, get_template
12
+ from BrowserApex.cli.apex import *
13
+
14
+ current_page = None
15
+
16
+
17
+
18
+ def build_structure():
19
+ regions = {}
20
+ for pageitem in current_page.page_items:
21
+ region_name = pageitem.layout.region
22
+ r = current_page.get_region(region_name)
23
+ if type(r) is list:
24
+ for reg in r:
25
+ if reg.type in ['Static Content', 'staticContent']:
26
+ region = reg
27
+ else:
28
+ region = r
29
+
30
+ name = region.name
31
+
32
+ if name not in regions:
33
+ regions[name] = dict(
34
+ region=region,
35
+ name=name,
36
+ fields=[],
37
+ page_buttons=[],
38
+ has_classic_report=False,
39
+ has_form=False,
40
+ is_wizard=False,
41
+ has_tabs=False
42
+ )
43
+ regions[name]['fields'].append(pageitem)
44
+
45
+ for button in current_page.buttons:
46
+ region_name = button.layout.region
47
+ r = current_page.get_region(region_name)
48
+ if type(r) is list:
49
+ for reg in r:
50
+ if reg.type in ['Static Content', 'staticContent']:
51
+ region = reg
52
+ else:
53
+ region = r
54
+
55
+ name = region.name
56
+
57
+ if name not in regions:
58
+ regions[name] = dict(
59
+ region=region,
60
+ name=name,
61
+ fields=[],
62
+ page_buttons=[],
63
+ has_classic_report=False,
64
+ has_form=False,
65
+ is_wizard=False,
66
+ has_tabs=False
67
+ )
68
+ regions[name]['page_buttons'].append(pageitem)
69
+
70
+ for r in regions.values():
71
+ # For fields we only need a label, id and type, example:
72
+ # ... Label=P1_NAME:TextField
73
+
74
+ # List is also sorted on sequence
75
+
76
+ newlist = [(x.label.label or x.name, x.name, x.type[0].upper() + x.type[1:]) for x in sorted(r['fields'], key=lambda d: d['layout']['sequence'])]
77
+ print(newlist)
78
+ r['fields'] = newlist
79
+
80
+ return regions
81
+
82
+ @app.command(name='generate')
83
+ def page_generate(
84
+ pagefile: Annotated[str, typer.Argument(help="The filename of exported page (yaml)")]
85
+ ):
86
+ """
87
+ Generate page object.
88
+
89
+ Existing page will be modified. Please do not remove the special comment lines!
90
+ Outside the special blocks existing code will be preserved.
91
+ Inside the special blocks existing code will be replaced.
92
+
93
+ """
94
+ global current_page
95
+
96
+ data = None
97
+ fn = Path(pagefile)
98
+ match fn.suffix:
99
+ case '.apx':
100
+ current_page = parse_apex_file(fn)
101
+ case '.yaml' | '.yml':
102
+ current_page = parse_yaml_file(fn)
103
+ case _:
104
+ raise RuntimeWarning("Unsupported file")
105
+
106
+ p = get_config_path()
107
+ if p is None:
108
+ print(f"No configuration found. Exitting...")
109
+ sys.exit(1)
110
+
111
+ print(f":beer: Reading config from: {p}")
112
+
113
+ cnf = get_config(p)
114
+ print(cnf)
115
+ template_path = p
116
+ main_template = get_template("pageobject", template_path)
117
+
118
+ pageobject_resource = f"{current_page.component_id}_{current_page.name.replace(' ','_')}.resource"
119
+ fn = p / cnf['output']['folder'] / pageobject_resource
120
+ if not fn.exists():
121
+ print(f":floppy_disk: Scaffolding resource {fn}")
122
+ with open(fn, 'w') as f:
123
+ f.write(main_template.render())
124
+
125
+ # TODO: Update main resource to include new pageobject resource
126
+
127
+ print(f":lab_coat: Processing page {current_page.component_id} - {current_page.name}")
128
+
129
+ regions = build_structure()
130
+ for name, region in regions.items():
131
+ print(f"{name} nr fields: {len(region['fields'])} button: {len(region['page_buttons'])}")
132
+
133
+
134
+ print(f":floppy_disk: Reading resource {fn}")
135
+ with open(fn, 'r') as f:
136
+ lines = f.readlines()
137
+
138
+ result = []
139
+ inside_block = False
140
+ for line in lines:
141
+ l = line.rstrip()
142
+
143
+ if l.startswith('### PAGEGEN:BEGIN:SETTINGS'):
144
+ inside_block = True
145
+
146
+ elif l.startswith('### PAGEGEN:END:SETTINGS'):
147
+ result.append('# TODO: SETTINGS')
148
+
149
+ inside_block = False
150
+
151
+ elif l.startswith('### PAGEGEN:BEGIN:VARIABLES'):
152
+ inside_block = True
153
+
154
+ elif l.startswith('### PAGEGEN:END:VARIABLES'):
155
+ variables_template = get_template('variables', template_path)
156
+ variables_lines = variables_template.render(page=current_page, blocks=regions)
157
+ result.extend(variables_lines.split("\n"))
158
+ inside_block = False
159
+
160
+ elif l.startswith('### PAGEGEN:BEGIN:KEYWORDS'):
161
+ inside_block = True
162
+
163
+ elif l.startswith('### PAGEGEN:END:KEYWORDS'):
164
+ result.append('# TODO: KEYWORDS')
165
+ inside_block = False
166
+
167
+ elif inside_block:
168
+ continue
169
+
170
+ result.append(l)
171
+
172
+ print(f":floppy_disk: Writing updated resource {fn}")
173
+ with open(fn, 'w') as f:
174
+ f.write("\n".join(result))
175
+
176
+
177
+
178
+ if __name__ == '__main__': # pragma: no cover
179
+
180
+ # page_generate('examples/test.apx')
181
+ # page_generate('examples/f300_page_9999.yaml')
182
+ page_generate('examples/f300_page_9999.yaml')