Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c42cc83aa1 | ||
|
|
106fc29c6a | ||
|
|
4218f8572d | ||
|
|
f0496b3d67 | ||
|
|
5ab89ce005 | ||
|
|
ec38d5f65f | ||
|
|
a0473cde1d | ||
|
|
97158d2006 | ||
|
|
394d2749bf | ||
|
|
9d16b20eb4 |
@@ -0,0 +1,395 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"diagram_type": "architecture",
|
||||
"meta": {
|
||||
"title": "PXIL Automation Runtime",
|
||||
"output": ".archify/architecture-pxil-runtime-20260929-151855/pxil-runtime.html",
|
||||
"quality_profile": "showcase",
|
||||
"locale": "en",
|
||||
"repository": {
|
||||
"url": "https://git.tejasshasane.xyz/tejasshasane/pxil-selenium-automation.git",
|
||||
"revision": "5ab89ce0059525b31558a1fa82251a2a6f610dd7",
|
||||
"link_mode": "local-only"
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"id": "runner",
|
||||
"type": "backend",
|
||||
"label": "pytest runner",
|
||||
"sublabel": "Selection + fixture lifecycle",
|
||||
"pos": [
|
||||
60,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 37,
|
||||
"end_line": 62
|
||||
},
|
||||
{
|
||||
"path": "pytest.ini",
|
||||
"line": 1,
|
||||
"end_line": 14
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "flows",
|
||||
"type": "backend",
|
||||
"label": "Automation flows",
|
||||
"sublabel": "Setup / bidding / matching",
|
||||
"pos": [
|
||||
360,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 54,
|
||||
"end_line": 90
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_exchange_matching_flow.py",
|
||||
"line": 76,
|
||||
"end_line": 156
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 13,
|
||||
"end_line": 37
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "browser",
|
||||
"type": "frontend",
|
||||
"label": "Chrome + WebDriver",
|
||||
"sublabel": "Selenium browser dependency",
|
||||
"pos": [
|
||||
680,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/browser.py",
|
||||
"line": 1,
|
||||
"end_line": 14
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/auth.py",
|
||||
"line": 46,
|
||||
"end_line": 86
|
||||
}
|
||||
],
|
||||
"tag": "Manual CAPTCHA for Pratyay"
|
||||
},
|
||||
{
|
||||
"id": "pratyay",
|
||||
"type": "external",
|
||||
"label": "Pratyay portal",
|
||||
"sublabel": "Exchange / member UI",
|
||||
"pos": [
|
||||
970,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 68,
|
||||
"end_line": 90
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_exchange_matching_flow.py",
|
||||
"line": 47,
|
||||
"end_line": 59
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "config",
|
||||
"type": "database",
|
||||
"label": "Configuration",
|
||||
"sublabel": "JSON + role credentials",
|
||||
"pos": [
|
||||
360,
|
||||
100
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/config_reader.py",
|
||||
"line": 6,
|
||||
"end_line": 32
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/config_reader.py",
|
||||
"line": 5,
|
||||
"end_line": 29
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/config_reader.py",
|
||||
"line": 121,
|
||||
"end_line": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "inputs",
|
||||
"type": "database",
|
||||
"label": "Bid input files",
|
||||
"sublabel": "Excel / JSON / upload folders",
|
||||
"pos": [
|
||||
360,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/input_manifest.py",
|
||||
"line": 4,
|
||||
"end_line": 28
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/json_reader.py",
|
||||
"line": 5,
|
||||
"end_line": 35
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 217,
|
||||
"end_line": 249
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "reporting",
|
||||
"type": "backend",
|
||||
"label": "Evidence reporting",
|
||||
"sublabel": "Step capture + pytest hooks",
|
||||
"pos": [
|
||||
60,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/step_actions.py",
|
||||
"line": 10,
|
||||
"end_line": 40
|
||||
},
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 104,
|
||||
"end_line": 175
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "artifacts",
|
||||
"type": "database",
|
||||
"label": "Run artifacts",
|
||||
"sublabel": "HTML / screenshots / logs",
|
||||
"pos": [
|
||||
60,
|
||||
770
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 37,
|
||||
"end_line": 48
|
||||
},
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 70,
|
||||
"end_line": 97
|
||||
},
|
||||
{
|
||||
"path": "tests/step_actions.py",
|
||||
"line": 21,
|
||||
"end_line": 35
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mco",
|
||||
"type": "external",
|
||||
"label": "MCO portal",
|
||||
"sublabel": "Independent login-only test",
|
||||
"pos": [
|
||||
970,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_mco_login.py",
|
||||
"line": 13,
|
||||
"end_line": 36
|
||||
}
|
||||
],
|
||||
"tag": "Only when enabled"
|
||||
}
|
||||
],
|
||||
"boundaries": [
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "LOCAL AUTOMATION HOST | trusted code, inputs and credentials",
|
||||
"wraps": [
|
||||
"runner",
|
||||
"flows",
|
||||
"browser",
|
||||
"config",
|
||||
"inputs",
|
||||
"reporting",
|
||||
"artifacts"
|
||||
],
|
||||
"pad": 28
|
||||
},
|
||||
{
|
||||
"kind": "security-group",
|
||||
"label": "Browser process boundary",
|
||||
"wraps": [
|
||||
"browser"
|
||||
],
|
||||
"pad": 18
|
||||
},
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "REMOTE PORTALS | separate authentication",
|
||||
"wraps": [
|
||||
"pratyay",
|
||||
"mco"
|
||||
],
|
||||
"pad": 28
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows",
|
||||
"label": "run tests",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "ui-actions",
|
||||
"from": "flows",
|
||||
"to": "browser",
|
||||
"label": "UI commands",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "portal-session",
|
||||
"from": "browser",
|
||||
"to": "pratyay",
|
||||
"label": "login + UI",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "read-settings",
|
||||
"from": "flows",
|
||||
"to": "config",
|
||||
"label": "read settings"
|
||||
},
|
||||
{
|
||||
"id": "read-bids",
|
||||
"from": "flows",
|
||||
"to": "inputs",
|
||||
"label": "read bids"
|
||||
},
|
||||
{
|
||||
"id": "report-hooks",
|
||||
"from": "runner",
|
||||
"to": "reporting",
|
||||
"label": "test hooks"
|
||||
},
|
||||
{
|
||||
"id": "write-evidence",
|
||||
"from": "reporting",
|
||||
"to": "artifacts",
|
||||
"label": "write evidence"
|
||||
},
|
||||
{
|
||||
"id": "optional-mco",
|
||||
"from": "browser",
|
||||
"to": "mco",
|
||||
"label": "if enabled: login",
|
||||
"variant": "dashed"
|
||||
}
|
||||
],
|
||||
"cards": [
|
||||
{
|
||||
"dot": "cyan",
|
||||
"title": "Primary path",
|
||||
"items": [
|
||||
"pytest runs selected tests; flow code controls Selenium and Chrome, which interacts with the remote Pratyay UI.",
|
||||
"Pratyay login fills credentials and pauses for manual CAPTCHA entry before submission (tests/regression/auth.py:46-122).",
|
||||
"Arrows describe control and I/O; results return to pytest. No direct backend API or database integration is asserted."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "violet",
|
||||
"title": "Flow selection and capabilities",
|
||||
"items": [
|
||||
"Root config.json selects setup products and session/token actions; config/runtime.json selects regression environment, role, product and flow.",
|
||||
"Bidding supports Excel/JSON grids, files and folders. Optional parallel folder workers create their own browsers (bidding flow:551-587).",
|
||||
"Matching requires the exchange role; rejected or unsupported bid-transfer status stops matching (matching flow:28-44, 123-135)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "rose",
|
||||
"title": "Trust and external dependencies",
|
||||
"items": [
|
||||
"Boundaries show host/process and remote ownership, not verified network isolation or firewall policy.",
|
||||
"Credentials come from local JSON and are entered into remote login forms. Values and endpoint addresses are omitted.",
|
||||
"Chrome/WebDriver is an external runtime dependency. Pratyay and MCO server internals and transport guarantees are outside the observed source.",
|
||||
"MCO is an independent, enabled-only dashboard login test; no Pratyay-to-MCO backend connection is inferred."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "emerald",
|
||||
"title": "Evidence and scope",
|
||||
"items": [
|
||||
"StepActions requests browser screenshots; pytest hooks attach evidence and configure pytest-html. Reports live under reports/.",
|
||||
"Matching configures browser downloads separately; setup can save session backups. These details are kept off the main path.",
|
||||
"Snapshot: clean repository at 5ab89ce0059525b31558a1fa82251a2a6f610dd7. Sources use local-only links.",
|
||||
"Registered reports/order-book/trade-book markers are placeholders, not implemented runtime services (RUN_COMMANDS.md)."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,721 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "browser-check",
|
||||
"evidenceKind": "automated-browser",
|
||||
"status": "pass",
|
||||
"visualReview": "not-requested",
|
||||
"provenance": "current",
|
||||
"deliveryReceiptId": "95e7d275-4f11-44f8-af68-086f2d8272bd",
|
||||
"artifact": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.html",
|
||||
"sha256": "3db6aa51a98c38d8aebafa9dd0682f3ea5c0ffd1d554c2ac6f000c94b73a193a",
|
||||
"bytes": 767845
|
||||
},
|
||||
"state": {
|
||||
"detail": "read",
|
||||
"motion": "still"
|
||||
},
|
||||
"chrome": {
|
||||
"status": "available",
|
||||
"executable": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"containment": {
|
||||
"status": "pass",
|
||||
"policy": "fit-or-reader-declared-readable-vertical-scroll",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 920,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 777,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1058,
|
||||
"diagramWidth": 1028,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 780,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNonEdgeTextPx": 7.534201954397394,
|
||||
"minimumProjectedEdgeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1163,
|
||||
"diagramWidth": 1133,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNonEdgeTextPx": 8.303745928338762,
|
||||
"minimumProjectedEdgeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1476,
|
||||
"diagramWidth": 1426,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"themeStates": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"requestedTheme": "dark",
|
||||
"resolvedTheme": "dark",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"requestedTheme": "dark",
|
||||
"resolvedTheme": "dark",
|
||||
"ok": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"readability": {
|
||||
"status": "pass",
|
||||
"minimumProjectedNodeTextPx": 6,
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 920,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 777,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1058,
|
||||
"diagramWidth": 1028,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 780,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNonEdgeTextPx": 7.534201954397394,
|
||||
"minimumProjectedEdgeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1163,
|
||||
"diagramWidth": 1133,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNonEdgeTextPx": 8.303745928338762,
|
||||
"minimumProjectedEdgeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1476,
|
||||
"diagramWidth": 1426,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewerChrome": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 920,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 777,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1058,
|
||||
"diagramWidth": 1028,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 780,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNonEdgeTextPx": 7.534201954397394,
|
||||
"minimumProjectedEdgeTextPx": 6.697068403908795,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1163,
|
||||
"diagramWidth": 1133,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNonEdgeTextPx": 8.303745928338762,
|
||||
"minimumProjectedEdgeTextPx": 7.381107491856677,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1476,
|
||||
"diagramWidth": 1426,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 932
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"captures": {
|
||||
"status": "not-requested",
|
||||
"screenshots": [],
|
||||
"contactSheet": null
|
||||
},
|
||||
"sidecars": {
|
||||
"receipt": "pxil-runtime.browser-check.json",
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"receiptId": "95e7d275-4f11-44f8-af68-086f2d8272bd",
|
||||
"status": "current",
|
||||
"command": "deliver",
|
||||
"type": "architecture",
|
||||
"input": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\candidate.json",
|
||||
"output": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.html",
|
||||
"specification": {
|
||||
"sha256": "5255f87576eeb3afd6713d933790d481cf9e8034f24453367adc240aa958ccbc",
|
||||
"bytes": 20698
|
||||
},
|
||||
"artifact": {
|
||||
"sha256": "3db6aa51a98c38d8aebafa9dd0682f3ea5c0ffd1d554c2ac6f000c94b73a193a",
|
||||
"bytes": 767845
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "finalize",
|
||||
"status": "pass",
|
||||
"type": "architecture",
|
||||
"quality": "showcase",
|
||||
"specification": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\candidate.json",
|
||||
"sha256": "5255f87576eeb3afd6713d933790d481cf9e8034f24453367adc240aa958ccbc",
|
||||
"bytes": 20698
|
||||
},
|
||||
"artifact": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.html",
|
||||
"sha256": "3db6aa51a98c38d8aebafa9dd0682f3ea5c0ffd1d554c2ac6f000c94b73a193a",
|
||||
"bytes": 767845
|
||||
},
|
||||
"gates": {
|
||||
"validate": "pass",
|
||||
"deliver": "pass",
|
||||
"check": "pass",
|
||||
"browser-check": "pass"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"diagnosticSummary": {
|
||||
"total": 0,
|
||||
"shown": 0,
|
||||
"truncated": false
|
||||
},
|
||||
"evidence": {
|
||||
"receipt": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.finalize.json",
|
||||
"summaryReceipt": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.finalize-summary.json",
|
||||
"browserCheckReceipt": "D:\\Selenium Test\\.archify\\architecture-pxil-runtime-20260929-151855\\pxil-runtime.browser-check.json"
|
||||
},
|
||||
"update": {
|
||||
"status": "current",
|
||||
"installedVersion": "3.0.1",
|
||||
"availableVersion": "3.0.1",
|
||||
"releaseNotes": null,
|
||||
"checkedAt": "2026-09-29T09:50:05.829Z",
|
||||
"source": "cache",
|
||||
"noticeRequired": false,
|
||||
"noticeText": null
|
||||
},
|
||||
"visualReview": "not-requested",
|
||||
"durationMs": 10625
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,461 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"diagram_type": "architecture",
|
||||
"meta": {
|
||||
"title": "PXIL Runtime: Sessions, Tokens and Regression",
|
||||
"output": ".archify/architecture-pxil-setup-runtime-20260929-155341/pxil-setup-runtime.html",
|
||||
"quality_profile": "showcase",
|
||||
"locale": "en",
|
||||
"repository": {
|
||||
"url": "https://git.tejasshasane.xyz/tejasshasane/pxil-selenium-automation.git",
|
||||
"revision": "5ab89ce0059525b31558a1fa82251a2a6f610dd7",
|
||||
"link_mode": "local-only"
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"id": "runner",
|
||||
"type": "backend",
|
||||
"label": "pytest runner",
|
||||
"sublabel": "Selection + fixture lifecycle",
|
||||
"pos": [
|
||||
60,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 37,
|
||||
"end_line": 62
|
||||
},
|
||||
{
|
||||
"path": "pytest.ini",
|
||||
"line": 1,
|
||||
"end_line": 14
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "flows",
|
||||
"type": "backend",
|
||||
"label": "Automation flows",
|
||||
"sublabel": "Setup / bidding / matching",
|
||||
"pos": [
|
||||
360,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 54,
|
||||
"end_line": 90
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_exchange_matching_flow.py",
|
||||
"line": 76,
|
||||
"end_line": 156
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 13,
|
||||
"end_line": 37
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "browser",
|
||||
"type": "frontend",
|
||||
"label": "Chrome + WebDriver",
|
||||
"sublabel": "Selenium browser dependency",
|
||||
"pos": [
|
||||
680,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/browser.py",
|
||||
"line": 1,
|
||||
"end_line": 14
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/auth.py",
|
||||
"line": 46,
|
||||
"end_line": 86
|
||||
}
|
||||
],
|
||||
"tag": "Manual CAPTCHA for Pratyay"
|
||||
},
|
||||
{
|
||||
"id": "pratyay",
|
||||
"type": "external",
|
||||
"label": "Pratyay portal",
|
||||
"sublabel": "Exchange / member UI",
|
||||
"pos": [
|
||||
970,
|
||||
300
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 68,
|
||||
"end_line": 90
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_exchange_matching_flow.py",
|
||||
"line": 47,
|
||||
"end_line": 59
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "config",
|
||||
"type": "database",
|
||||
"label": "Config + bid inputs",
|
||||
"sublabel": "JSON / Excel / upload folders",
|
||||
"pos": [
|
||||
360,
|
||||
100
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/config_reader.py",
|
||||
"line": 6,
|
||||
"end_line": 32
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/config_reader.py",
|
||||
"line": 5,
|
||||
"end_line": 29
|
||||
},
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/bidding/test_idas_exchange_bidding_flow.py",
|
||||
"line": 217,
|
||||
"end_line": 249
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "reporting",
|
||||
"type": "backend",
|
||||
"label": "Evidence reporting",
|
||||
"sublabel": "Step capture + pytest hooks",
|
||||
"pos": [
|
||||
60,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/step_actions.py",
|
||||
"line": 10,
|
||||
"end_line": 40
|
||||
},
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 104,
|
||||
"end_line": 175
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "artifacts",
|
||||
"type": "database",
|
||||
"label": "Run artifacts",
|
||||
"sublabel": "HTML / screenshots / logs",
|
||||
"pos": [
|
||||
60,
|
||||
770
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 37,
|
||||
"end_line": 48
|
||||
},
|
||||
{
|
||||
"path": "tests/conftest.py",
|
||||
"line": 70,
|
||||
"end_line": 97
|
||||
},
|
||||
{
|
||||
"path": "tests/step_actions.py",
|
||||
"line": 21,
|
||||
"end_line": 35
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mco",
|
||||
"type": "external",
|
||||
"label": "MCO portal",
|
||||
"sublabel": "Independent login-only test",
|
||||
"pos": [
|
||||
970,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/regression/exchange/idas/matching/test_idas_mco_login.py",
|
||||
"line": 13,
|
||||
"end_line": 36
|
||||
}
|
||||
],
|
||||
"tag": "Only when enabled"
|
||||
},
|
||||
{
|
||||
"id": "sessions",
|
||||
"type": "backend",
|
||||
"label": "Trading session setup",
|
||||
"sublabel": "ME instance + times + Save",
|
||||
"tag": "When run_session = true",
|
||||
"pos": [
|
||||
360,
|
||||
560
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/sessions/test_session.py",
|
||||
"line": 24,
|
||||
"end_line": 64
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 21,
|
||||
"end_line": 37
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "tokens",
|
||||
"type": "backend",
|
||||
"label": "Trading token setup",
|
||||
"sublabel": "Per product code + Save",
|
||||
"tag": "When run_token = true",
|
||||
"pos": [
|
||||
360,
|
||||
800
|
||||
],
|
||||
"size": [
|
||||
190,
|
||||
74
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 150,
|
||||
"end_line": 180
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 212,
|
||||
"end_line": 326
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 328,
|
||||
"end_line": 342
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"boundaries": [
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "LOCAL AUTOMATION HOST | trusted code, inputs and credentials",
|
||||
"wraps": [
|
||||
"runner",
|
||||
"flows",
|
||||
"browser",
|
||||
"config",
|
||||
"reporting",
|
||||
"artifacts",
|
||||
"sessions",
|
||||
"tokens"
|
||||
],
|
||||
"pad": 28
|
||||
},
|
||||
{
|
||||
"kind": "security-group",
|
||||
"label": "Browser process boundary",
|
||||
"wraps": [
|
||||
"browser"
|
||||
],
|
||||
"pad": 18
|
||||
},
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "REMOTE PORTALS | separate authentication",
|
||||
"wraps": [
|
||||
"pratyay",
|
||||
"mco"
|
||||
],
|
||||
"pad": 28
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows",
|
||||
"label": "run tests",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "ui-actions",
|
||||
"from": "flows",
|
||||
"to": "browser",
|
||||
"label": "UI commands",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "portal-session",
|
||||
"from": "browser",
|
||||
"to": "pratyay",
|
||||
"label": "login + UI",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "read-settings",
|
||||
"from": "flows",
|
||||
"to": "config",
|
||||
"label": "read files"
|
||||
},
|
||||
{
|
||||
"id": "report-hooks",
|
||||
"from": "runner",
|
||||
"to": "reporting",
|
||||
"label": "test hooks"
|
||||
},
|
||||
{
|
||||
"id": "write-evidence",
|
||||
"from": "reporting",
|
||||
"to": "artifacts",
|
||||
"label": "write evidence"
|
||||
},
|
||||
{
|
||||
"id": "optional-mco",
|
||||
"from": "browser",
|
||||
"to": "mco",
|
||||
"label": "if enabled: login",
|
||||
"variant": "dashed"
|
||||
},
|
||||
{
|
||||
"id": "session-enabled",
|
||||
"from": "flows",
|
||||
"to": "sessions",
|
||||
"label": "run_session",
|
||||
"variant": "default"
|
||||
},
|
||||
{
|
||||
"id": "combined-order",
|
||||
"from": "sessions",
|
||||
"to": "tokens",
|
||||
"label": "both enabled: next",
|
||||
"variant": "dashed"
|
||||
},
|
||||
{
|
||||
"id": "token-only",
|
||||
"from": "flows",
|
||||
"to": "tokens",
|
||||
"label": "token only",
|
||||
"variant": "default",
|
||||
"fromSide": "bottom",
|
||||
"toSide": "right"
|
||||
}
|
||||
],
|
||||
"cards": [
|
||||
{
|
||||
"dot": "amber",
|
||||
"title": "Session and token execution",
|
||||
"items": [
|
||||
"After setup login and manual CAPTCHA: session-only runs create_session; token-only runs run_token_setup; combined runs create_session then run_token_setup for each product code.",
|
||||
"Both setup modules use the shared Selenium driver and StepActions through Automation flows. The dashed session-to-token arrow denotes controller ordering, not a direct module call (tests/setup/test_combined_setup.py:21-37).",
|
||||
"Session creation opens Trading Session, selects the ME instance, fills start/end times, then clicks Save (tests/setup/sessions/test_session.py:24-40).",
|
||||
"These are trading sessions and trading tokens, distinct from browser authentication/session backups."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "orange",
|
||||
"title": "Product-specific token behavior",
|
||||
"items": [
|
||||
"IDAS/default branch: create token, set delivery dates and expiry, Save, edit ORDER_NOR / ORDER_EXCH / TRADE times, then Save and Activate (tests/setup/tokens/test_trading_token.py:150-180, 264-325).",
|
||||
"RTM branch fills delivery and session times and saves the token; activation is not called (lines 212-225, 254-261).",
|
||||
"UPC branch fills configured order/trade times, saves, then resets the generator (lines 228-258).",
|
||||
"config.json selects enabled products and run_session/run_token flags. Disabled products and both-false products are omitted; UPC variants have additional routing rules (tests/config_reader.py:36-83)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "cyan",
|
||||
"title": "Primary path",
|
||||
"items": [
|
||||
"pytest runs selected tests; flow code controls Selenium and Chrome, which interacts with the remote Pratyay UI.",
|
||||
"Pratyay login fills credentials and pauses for manual CAPTCHA entry before submission (tests/regression/auth.py:46-122).",
|
||||
"Arrows describe control and I/O; results return to pytest. No direct backend API or database integration is asserted."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "violet",
|
||||
"title": "Flow selection and capabilities",
|
||||
"items": [
|
||||
"Root config.json selects setup products and session/token actions; config/runtime.json selects regression environment, role, product and flow.",
|
||||
"Bidding supports Excel/JSON grids, files and folders. Optional parallel folder workers create their own browsers (bidding flow:551-587).",
|
||||
"Matching requires the exchange role; rejected or unsupported bid-transfer status stops matching (matching flow:28-44, 123-135)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "rose",
|
||||
"title": "Trust and external dependencies",
|
||||
"items": [
|
||||
"Boundaries show host/process and remote ownership, not verified network isolation or firewall policy.",
|
||||
"Credentials come from local JSON and are entered into remote login forms. Values and endpoint addresses are omitted.",
|
||||
"Chrome/WebDriver is an external runtime dependency. Pratyay and MCO server internals and transport guarantees are outside the observed source.",
|
||||
"MCO is an independent, enabled-only dashboard login test; no Pratyay-to-MCO backend connection is inferred."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "emerald",
|
||||
"title": "Evidence and scope",
|
||||
"items": [
|
||||
"StepActions requests browser screenshots; pytest hooks attach evidence and configure pytest-html. Reports live under reports/.",
|
||||
"Matching configures browser downloads separately; setup can save session backups. These details are kept off the main path.",
|
||||
"Source snapshot: 5ab89ce0059525b31558a1fa82251a2a6f610dd7; tracked code unchanged. Only generated .archify/ artifacts are untracked. Sources use local-only links.",
|
||||
"Registered reports/order-book/trade-book markers are placeholders, not implemented runtime services (RUN_COMMANDS.md)."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+721
@@ -0,0 +1,721 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "browser-check",
|
||||
"evidenceKind": "automated-browser",
|
||||
"status": "pass",
|
||||
"visualReview": "not-requested",
|
||||
"provenance": "current",
|
||||
"deliveryReceiptId": "4a5fda98-da80-480c-a108-3987d32a0fb2",
|
||||
"artifact": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.html",
|
||||
"sha256": "7f1a2d9fcc2ed49fc6a2c2c9c541bd0620ab0ca1cf04b5e388dae27d01e5b3ec",
|
||||
"bytes": 773779
|
||||
},
|
||||
"state": {
|
||||
"detail": "read",
|
||||
"motion": "still"
|
||||
},
|
||||
"chrome": {
|
||||
"status": "available",
|
||||
"executable": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"containment": {
|
||||
"status": "pass",
|
||||
"policy": "fit-or-reader-declared-readable-vertical-scroll",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 945,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1011,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1128,
|
||||
"diagramWidth": 1098,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNonEdgeTextPx": 8.047231270358306,
|
||||
"minimumProjectedEdgeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1431,
|
||||
"diagramWidth": 1381,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"themeStates": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"requestedTheme": "light",
|
||||
"resolvedTheme": "light",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"requestedTheme": "dark",
|
||||
"resolvedTheme": "dark",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"requestedTheme": "dark",
|
||||
"resolvedTheme": "dark",
|
||||
"ok": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"readability": {
|
||||
"status": "pass",
|
||||
"minimumProjectedNodeTextPx": 6,
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 945,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1011,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1128,
|
||||
"diagramWidth": 1098,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNonEdgeTextPx": 8.047231270358306,
|
||||
"minimumProjectedEdgeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1431,
|
||||
"diagramWidth": 1381,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewerChrome": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 945,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 12,
|
||||
"headerPx": 52,
|
||||
"diagramChromePx": 78,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1011,
|
||||
"overflowX": false,
|
||||
"overflowY": true,
|
||||
"verticalScrollAccepted": true,
|
||||
"overflowDisposition": "readable-vertical-scroll",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": "authored",
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1054,
|
||||
"diagramWidth": 1024,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 802,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNonEdgeTextPx": 7.504885993485343,
|
||||
"minimumProjectedEdgeTextPx": 6.671009771986971,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1128,
|
||||
"diagramWidth": 1098,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 60,
|
||||
"diagramChromePx": 84,
|
||||
"svgPx": 860,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNonEdgeTextPx": 8.047231270358306,
|
||||
"minimumProjectedEdgeTextPx": 7.153094462540716,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 54,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"verticalScrollAccepted": false,
|
||||
"overflowDisposition": "contained",
|
||||
"readerLayout": "adaptive",
|
||||
"readerOverflow": null,
|
||||
"readerFit": "intrinsic-height",
|
||||
"ok": true,
|
||||
"readerWidth": 1431,
|
||||
"diagramWidth": 1381,
|
||||
"pageComposition": {
|
||||
"bodyPaddingPx": 64,
|
||||
"headerPx": 68,
|
||||
"diagramChromePx": 94,
|
||||
"svgPx": 1082,
|
||||
"cardsPx": 0,
|
||||
"viewBoxHeight": 962
|
||||
},
|
||||
"viewBoxWidth": 1228,
|
||||
"minimumProjectedNodeTextPx": 8,
|
||||
"minimumProjectedNonEdgeTextPx": 9,
|
||||
"minimumProjectedEdgeTextPx": 8,
|
||||
"minimumProjectedNodeText": "run tests",
|
||||
"minimumProjectedNodeTextDetail": "edge",
|
||||
"minimumProjectedNodeTextOwner": {
|
||||
"kind": "edge",
|
||||
"id": "selected-tests",
|
||||
"from": "runner",
|
||||
"to": "flows"
|
||||
},
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 44,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"captures": {
|
||||
"status": "not-requested",
|
||||
"screenshots": [],
|
||||
"contactSheet": null
|
||||
},
|
||||
"sidecars": {
|
||||
"receipt": "pxil-setup-runtime.browser-check.json",
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"receiptId": "4a5fda98-da80-480c-a108-3987d32a0fb2",
|
||||
"status": "current",
|
||||
"command": "deliver",
|
||||
"type": "architecture",
|
||||
"input": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\candidate.json",
|
||||
"output": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.html",
|
||||
"specification": {
|
||||
"sha256": "1419cbca3fed61e28342a8b9767aa43fa85a7b18ff380e93ebedccfa96f9549b",
|
||||
"bytes": 25091
|
||||
},
|
||||
"artifact": {
|
||||
"sha256": "7f1a2d9fcc2ed49fc6a2c2c9c541bd0620ab0ca1cf04b5e388dae27d01e5b3ec",
|
||||
"bytes": 773779
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "finalize",
|
||||
"status": "pass",
|
||||
"type": "architecture",
|
||||
"quality": "showcase",
|
||||
"specification": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\candidate.json",
|
||||
"sha256": "1419cbca3fed61e28342a8b9767aa43fa85a7b18ff380e93ebedccfa96f9549b",
|
||||
"bytes": 25091
|
||||
},
|
||||
"artifact": {
|
||||
"path": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.html",
|
||||
"sha256": "7f1a2d9fcc2ed49fc6a2c2c9c541bd0620ab0ca1cf04b5e388dae27d01e5b3ec",
|
||||
"bytes": 773779
|
||||
},
|
||||
"gates": {
|
||||
"validate": "pass",
|
||||
"deliver": "pass",
|
||||
"check": "pass",
|
||||
"browser-check": "pass"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"diagnosticSummary": {
|
||||
"total": 0,
|
||||
"shown": 0,
|
||||
"truncated": false
|
||||
},
|
||||
"evidence": {
|
||||
"receipt": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.finalize.json",
|
||||
"summaryReceipt": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.finalize-summary.json",
|
||||
"browserCheckReceipt": "D:\\Selenium Test\\.archify\\architecture-pxil-setup-runtime-20260929-155341\\pxil-setup-runtime.browser-check.json"
|
||||
},
|
||||
"update": {
|
||||
"status": "current",
|
||||
"installedVersion": "3.0.1",
|
||||
"availableVersion": "3.0.1",
|
||||
"releaseNotes": null,
|
||||
"checkedAt": "2026-09-29T09:50:05.829Z",
|
||||
"source": "cache",
|
||||
"noticeRequired": false,
|
||||
"noticeText": null
|
||||
},
|
||||
"visualReview": "not-requested",
|
||||
"durationMs": 10108,
|
||||
"visualReviewRecommendation": {
|
||||
"action": "inspect-route-readability",
|
||||
"signals": {
|
||||
"routesOverSuggestedBends": 1
|
||||
},
|
||||
"reason": "Automated gates passed, but crossings or detours still need perceptual review before claiming visual quality.",
|
||||
"affectedRoutes": {
|
||||
"crossings": [],
|
||||
"detours": [
|
||||
{
|
||||
"relationship": {
|
||||
"id": "token-only",
|
||||
"from": "flows",
|
||||
"to": "tokens",
|
||||
"label": "token only",
|
||||
"collectionIndex": 9,
|
||||
"artifactIndex": 10
|
||||
},
|
||||
"bends": 3,
|
||||
"stretch": 1.087,
|
||||
"directCorridorBlockers": [
|
||||
{
|
||||
"id": "sessions",
|
||||
"label": "Trading session setup",
|
||||
"box": [
|
||||
360,
|
||||
560,
|
||||
190,
|
||||
74
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"truncated": false
|
||||
},
|
||||
"repair": "Trace these relationships at the desktop viewport. For Architecture, use references/architecture-layout-repair.md: reflow a blocked main path or tangled connected scene, and repair an isolated defect locally only when the surrounding composition is accepted. Preserve all semantic content and user-fixed geometry. Rerun finalize once after the edit."
|
||||
}
|
||||
}
|
||||
+1041
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,430 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"diagram_type": "workflow",
|
||||
"meta": {
|
||||
"title": "PXIL Session + Trading Token Setup",
|
||||
"subtitle": "Configuration-driven pytest/Selenium workflow",
|
||||
"output": ".archify/workflow-pxil-session-token-20260929-160100/pxil-session-token.html",
|
||||
"quality_profile": "showcase",
|
||||
"animation": "none",
|
||||
"repository": {
|
||||
"url": "https://git.tejasshasane.xyz/tejasshasane/pxil-selenium-automation.git",
|
||||
"revision": "5ab89ce0059525b31558a1fa82251a2a6f610dd7",
|
||||
"link_mode": "local-only"
|
||||
}
|
||||
},
|
||||
"lanes": [
|
||||
{
|
||||
"id": "config",
|
||||
"label": "Configuration \u0026 selection"
|
||||
},
|
||||
{
|
||||
"id": "pytest",
|
||||
"label": "Pytest orchestration"
|
||||
},
|
||||
{
|
||||
"id": "browser",
|
||||
"label": "Browser automation"
|
||||
},
|
||||
{
|
||||
"id": "portal",
|
||||
"label": "Pratyay portal"
|
||||
}
|
||||
],
|
||||
"phases": [
|
||||
{
|
||||
"id": "resolve",
|
||||
"label": "Resolve run",
|
||||
"fromCol": 0,
|
||||
"toCol": 1
|
||||
},
|
||||
{
|
||||
"id": "login",
|
||||
"label": "Authenticate",
|
||||
"fromCol": 2,
|
||||
"toCol": 2,
|
||||
"variant": "security"
|
||||
},
|
||||
{
|
||||
"id": "setup",
|
||||
"label": "Create session + tokens",
|
||||
"fromCol": 3,
|
||||
"toCol": 4,
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "evidence",
|
||||
"label": "Capture evidence",
|
||||
"fromCol": 5,
|
||||
"toCol": 5,
|
||||
"variant": "dashed"
|
||||
}
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"id": "config_group",
|
||||
"label": "Product and mode resolution",
|
||||
"lane": "config",
|
||||
"fromCol": 0,
|
||||
"toCol": 1,
|
||||
"variant": "dashed"
|
||||
},
|
||||
{
|
||||
"id": "auth_group",
|
||||
"label": "One browser login",
|
||||
"lane": "browser",
|
||||
"fromCol": 2,
|
||||
"toCol": 2,
|
||||
"variant": "security"
|
||||
},
|
||||
{
|
||||
"id": "session_group",
|
||||
"label": "Session creation gate",
|
||||
"lane": "portal",
|
||||
"fromCol": 3,
|
||||
"toCol": 3,
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "token_group",
|
||||
"label": "Token creation loop",
|
||||
"lane": "portal",
|
||||
"fromCol": 4,
|
||||
"toCol": 5,
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "evidence_group",
|
||||
"label": "Step artifacts",
|
||||
"lane": "config",
|
||||
"fromCol": 5,
|
||||
"toCol": 5,
|
||||
"variant": "dashed"
|
||||
}
|
||||
],
|
||||
"mainPath": [
|
||||
"pytest_start",
|
||||
"load_config",
|
||||
"parametrize",
|
||||
"driver_login",
|
||||
"token_dispatch",
|
||||
"token_save",
|
||||
"save_report"
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "pytest_start",
|
||||
"lane": "pytest",
|
||||
"col": 0,
|
||||
"type": "backend",
|
||||
"label": "Pytest setup test",
|
||||
"sublabel": "test_combined_setup.py",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 11,
|
||||
"end_line": 14
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "load_config",
|
||||
"lane": "config",
|
||||
"col": 1,
|
||||
"type": "database",
|
||||
"label": "Load config.json",
|
||||
"sublabel": "products + setup flags",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/config_reader.py",
|
||||
"line": 6,
|
||||
"end_line": 33
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "parametrize",
|
||||
"lane": "config",
|
||||
"col": 2,
|
||||
"type": "backend",
|
||||
"label": "get_setup_configs",
|
||||
"sublabel": "combined / session / token",
|
||||
"tag": "skip disabled",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/config_reader.py",
|
||||
"line": 36,
|
||||
"end_line": 83
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "driver_login",
|
||||
"lane": "browser",
|
||||
"col": 2,
|
||||
"type": "security",
|
||||
"label": "Open + login",
|
||||
"sublabel": "Chrome, credentials, CAPTCHA",
|
||||
"tag": "manual CAPTCHA",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 21,
|
||||
"end_line": 29
|
||||
},
|
||||
{
|
||||
"path": "tests/helpers.py",
|
||||
"line": 60,
|
||||
"end_line": 91
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "session_gate",
|
||||
"lane": "pytest",
|
||||
"col": 3,
|
||||
"type": "security",
|
||||
"label": "run_session?",
|
||||
"sublabel": "product flag gate",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 31,
|
||||
"end_line": 32
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "session_create",
|
||||
"lane": "portal",
|
||||
"col": 3,
|
||||
"type": "backend",
|
||||
"label": "create_session",
|
||||
"sublabel": "ME instance + dates -\u003e Save",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/sessions/test_session.py",
|
||||
"line": 24,
|
||||
"end_line": 40
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "token_loop",
|
||||
"lane": "pytest",
|
||||
"col": 4,
|
||||
"type": "backend",
|
||||
"label": "Product-code loop",
|
||||
"sublabel": "one token per configured code",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 34,
|
||||
"end_line": 37
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 74,
|
||||
"end_line": 83
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "token_dispatch",
|
||||
"lane": "portal",
|
||||
"col": 4,
|
||||
"type": "backend",
|
||||
"label": "run_token_setup",
|
||||
"sublabel": "IDAS / RTM / UPC branch",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 254,
|
||||
"end_line": 262
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "token_save",
|
||||
"lane": "portal",
|
||||
"col": 5,
|
||||
"type": "backend",
|
||||
"label": "Create + save token",
|
||||
"sublabel": "dates, expiry, time sessions",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 264,
|
||||
"end_line": 325
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "save_report",
|
||||
"lane": "config",
|
||||
"col": 5,
|
||||
"type": "database",
|
||||
"label": "Evidence + teardown",
|
||||
"sublabel": "screenshots, backup, logout",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/step_actions.py",
|
||||
"line": 21,
|
||||
"end_line": 40
|
||||
},
|
||||
{
|
||||
"path": "tests/helpers.py",
|
||||
"line": 135,
|
||||
"end_line": 159
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 330,
|
||||
"end_line": 342
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "session_skip",
|
||||
"lane": "config",
|
||||
"col": 3,
|
||||
"type": "messagebus",
|
||||
"label": "Skip session",
|
||||
"sublabel": "run_session = false",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/test_combined_setup.py",
|
||||
"line": 31,
|
||||
"end_line": 32
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "pratyay_ui",
|
||||
"lane": "portal",
|
||||
"col": 2,
|
||||
"type": "external",
|
||||
"label": "Pratyay UI",
|
||||
"sublabel": "Trading maintenance pages",
|
||||
"width": 150,
|
||||
"sources": [
|
||||
{
|
||||
"path": "tests/setup/sessions/test_session.py",
|
||||
"line": 28,
|
||||
"end_line": 40
|
||||
},
|
||||
{
|
||||
"path": "tests/setup/tokens/test_trading_token.py",
|
||||
"line": 274,
|
||||
"end_line": 325
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "start-config",
|
||||
"from": "pytest_start",
|
||||
"to": "load_config",
|
||||
"label": "collect + resolve",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "config-param",
|
||||
"from": "load_config",
|
||||
"to": "parametrize",
|
||||
"label": "product settings"
|
||||
},
|
||||
{
|
||||
"id": "param-login",
|
||||
"from": "parametrize",
|
||||
"to": "driver_login",
|
||||
"label": "selected config",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "login-portal",
|
||||
"from": "driver_login",
|
||||
"to": "pratyay_ui",
|
||||
"label": "authenticate",
|
||||
"variant": "security"
|
||||
},
|
||||
{
|
||||
"id": "skip-token-loop",
|
||||
"from": "session_skip",
|
||||
"to": "token_loop",
|
||||
"label": "token-only / combined decision",
|
||||
"variant": "dashed"
|
||||
},
|
||||
{
|
||||
"id": "dispatch-save",
|
||||
"from": "token_dispatch",
|
||||
"to": "token_save",
|
||||
"label": "IDAS default",
|
||||
"variant": "emphasis"
|
||||
},
|
||||
{
|
||||
"id": "save-evidence",
|
||||
"from": "token_save",
|
||||
"to": "save_report",
|
||||
"label": "step captures",
|
||||
"variant": "dashed"
|
||||
},
|
||||
{
|
||||
"id": "login-dispatch",
|
||||
"from": "driver_login",
|
||||
"to": "token_dispatch",
|
||||
"label": "run token flow",
|
||||
"variant": "emphasis"
|
||||
}
|
||||
],
|
||||
"cards": [
|
||||
{
|
||||
"dot": "cyan",
|
||||
"title": "How configuration is called",
|
||||
"items": [
|
||||
"pytest parametrization calls get_setup_configs(\"combined\") when test_session_and_token_setup is collected.",
|
||||
"get_product_config merges product overrides into setup.run_session/run_token and resolves token settings; disabled products are filtered out.",
|
||||
"Each selected config carries url, login, product.me_instance, token settings and product_name into the test."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "amber",
|
||||
"title": "Combined run semantics",
|
||||
"items": [
|
||||
"The test opens the portal and logs in once per browser fixture. It saves a browser cookie/session backup after login.",
|
||||
"When run_session is true, create_session selects the configured ME instance and saves the calculated start/end window.",
|
||||
"The same driver then loops product codes and calls run_token_setup for each one."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "violet",
|
||||
"title": "Token branches",
|
||||
"items": [
|
||||
"IDAS/default creates the token, fills delivery/expiry values, then edits ORDER_NOR, ORDER_EXCH and TRADE time sessions before Save and Activate.",
|
||||
"RTM selects market/product/generation mode, fills delivery and session times, then saves; activation is not part of this branch.",
|
||||
"UPC fills configured order/trade times, saves, then resets the generator."
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "rose",
|
||||
"title": "Authentication and evidence",
|
||||
"items": [
|
||||
"login() sends credentials, waits for manual CAPTCHA completion, submits, waits for the dashboard marker and closes transient notices.",
|
||||
"StepActions captures screenshots after interactions. conftest.py attaches them to pytest-html and creates report folders.",
|
||||
"The diagram shows trading sessions/tokens; login session backups are browser cookies, not the trading-session records created in the portal."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+1345
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"receiptId": "194f6ca1-621e-45b4-ab5d-d915aa4711fd",
|
||||
"status": "current",
|
||||
"command": "deliver",
|
||||
"type": "workflow",
|
||||
"input": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\candidate.json",
|
||||
"output": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\pxil-session-token.html",
|
||||
"specification": {
|
||||
"sha256": "c349c44844d853c1dc013cd9f1e9380b0f1548224ef389a1960b97af956310b1",
|
||||
"bytes": 19583
|
||||
},
|
||||
"artifact": {
|
||||
"sha256": "d0c3abadeefa664a3d46893e7dc43042339bf42471f76967fe467600f0388882",
|
||||
"bytes": 771409
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "finalize",
|
||||
"status": "pass",
|
||||
"type": "workflow",
|
||||
"quality": "showcase",
|
||||
"specification": {
|
||||
"path": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\candidate.json",
|
||||
"sha256": "c349c44844d853c1dc013cd9f1e9380b0f1548224ef389a1960b97af956310b1",
|
||||
"bytes": 19583
|
||||
},
|
||||
"artifact": {
|
||||
"path": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\pxil-session-token.html",
|
||||
"sha256": "d0c3abadeefa664a3d46893e7dc43042339bf42471f76967fe467600f0388882",
|
||||
"bytes": 771409
|
||||
},
|
||||
"gates": {
|
||||
"validate": "pass",
|
||||
"deliver": "pass",
|
||||
"check": "pass",
|
||||
"browser-check": "pass"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"diagnosticSummary": {
|
||||
"total": 0,
|
||||
"shown": 0,
|
||||
"truncated": false
|
||||
},
|
||||
"evidence": {
|
||||
"receipt": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\pxil-session-token.finalize.json",
|
||||
"summaryReceipt": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\pxil-session-token.finalize-summary.json",
|
||||
"browserCheckReceipt": "D:\\Selenium Test\\.archify\\workflow-pxil-session-token-20260929-160100\\pxil-session-token.browser-check.json"
|
||||
},
|
||||
"update": {
|
||||
"status": "current",
|
||||
"installedVersion": "3.0.1",
|
||||
"availableVersion": "3.0.1",
|
||||
"releaseNotes": null,
|
||||
"checkedAt": "2026-09-29T09:50:05.829Z",
|
||||
"source": "cache",
|
||||
"noticeRequired": false,
|
||||
"noticeText": null
|
||||
},
|
||||
"visualReview": "not-requested",
|
||||
"durationMs": 12243,
|
||||
"visualReviewRecommendation": {
|
||||
"action": "inspect-route-readability",
|
||||
"signals": {
|
||||
"routesOverSuggestedBends": 2
|
||||
},
|
||||
"reason": "Automated gates passed, but crossings or detours still need perceptual review before claiming visual quality.",
|
||||
"affectedRoutes": {
|
||||
"crossings": [],
|
||||
"detours": [
|
||||
{
|
||||
"relationship": {
|
||||
"id": "login-dispatch",
|
||||
"from": "driver_login",
|
||||
"to": "token_dispatch",
|
||||
"label": "run token flow",
|
||||
"collectionIndex": 2,
|
||||
"artifactIndex": 3
|
||||
},
|
||||
"bends": 3,
|
||||
"stretch": 1.164
|
||||
},
|
||||
{
|
||||
"relationship": {
|
||||
"id": "param-login",
|
||||
"from": "parametrize",
|
||||
"to": "driver_login",
|
||||
"label": "selected config",
|
||||
"collectionIndex": 4,
|
||||
"artifactIndex": 5
|
||||
},
|
||||
"bends": 3,
|
||||
"stretch": 1.109
|
||||
}
|
||||
],
|
||||
"truncated": false
|
||||
},
|
||||
"hints": [
|
||||
"driver_login → token_dispatch needs 3 bends: move node driver_login or token_dispatch so they share a row or column with matching centers, or sit diagonally with a clear corner.",
|
||||
"parametrize → driver_login needs 3 bends: move node parametrize or driver_login so they share a row or column with matching centers, or sit diagonally with a clear corner."
|
||||
],
|
||||
"repair": "Trace these relationships at the desktop viewport. For Architecture, use references/architecture-layout-repair.md: reflow a blocked main path or tangled connected scene, and repair an isolated defect locally only when the surrounding composition is accepted. Preserve all semantic content and user-fixed geometry. Rerun finalize once after the edit."
|
||||
}
|
||||
}
|
||||
+1657
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -9,6 +9,9 @@ __pycache__/
|
||||
# Pytest cache
|
||||
.pytest_cache/
|
||||
|
||||
# Machine-specific test configuration
|
||||
config.json
|
||||
|
||||
# Generated reports (keep directory structure)
|
||||
reports/screenshots/*
|
||||
!reports/screenshots/.gitkeep
|
||||
|
||||
+75
-1
@@ -11,6 +11,80 @@ cd "C:\Selenium Test"
|
||||
|
||||
Edit `config.json` before running.
|
||||
|
||||
Common URL, login credentials, login waits, and step delay stay at the top level.
|
||||
`setup.run_session` and `setup.run_token` are defaults for every enabled product.
|
||||
`setup.session` provides common session timing defaults.
|
||||
|
||||
`products` contains separate `IDAS`, `RTM`, `UPC`, `RA`, and `REC` sections.
|
||||
Each product has its own `me_instance`, optional `session` timing overrides, and
|
||||
`token` settings (codes, delivery offset, expiry, and time sessions).
|
||||
RTM currently runs token creation only (`run_session: false`, `run_token: true`).
|
||||
If enabled again, session creation uses ME instance
|
||||
`52` (`52:RTM`). It uses today's date plus a 7-minute start offset and today's
|
||||
`20:30` end time, matching the current IDAS session end-time default. Change
|
||||
`products.RTM.session.start_offset_minutes` and `products.RTM.session.end_time`
|
||||
to configure RTM independently. The shared login, navigation, and Save steps apply
|
||||
to every product. RTM token automation opens Token Generator,
|
||||
selects `NATIONAL`, product code `RTM`, and generation mode `RTM`, then clicks
|
||||
Add New Token. Product Type is populated automatically. It fills delivery dates
|
||||
with today's `00:00` and `23:59`, session start with current time plus 5 minutes,
|
||||
and session end with `20:00`, then clicks Save Token. All four timings are
|
||||
configured under `products.RTM.token` as shown below. `delivery_offset_days: 0`
|
||||
means today. RTM activation is not part of this stage.
|
||||
|
||||
Run RTM token creation through Save Token:
|
||||
|
||||
```powershell
|
||||
pytest tests\setup -k RTM -s
|
||||
```
|
||||
|
||||
Existing IDAS settings are preserved. The remaining product templates are disabled until
|
||||
you fill in their actual ME instance/token codes and set `enabled` to `true`.
|
||||
Additional products can be added using the same structure.
|
||||
|
||||
To override the defaults for one product, add flags directly inside that product:
|
||||
|
||||
```json
|
||||
"RTM": {
|
||||
"enabled": true,
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"me_instance": "52",
|
||||
"session": {
|
||||
"start_offset_minutes": 7,
|
||||
"end_time": "20:30"
|
||||
},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "RTM",
|
||||
"product_codes": ["RTM"],
|
||||
"generation_mode": "RTM",
|
||||
"delivery_offset_days": 0,
|
||||
"delivery_from_time": "00:00",
|
||||
"delivery_to_time": "23:59",
|
||||
"session_start_offset_minutes": 5,
|
||||
"session_end_time": "20:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Remove a product's `run_session` or `run_token` key to inherit that common flag
|
||||
again. Explicit `false` overrides a common `true`; explicit `true` overrides a
|
||||
common `false`. Both false skips that product; `enabled: false` always skips it.
|
||||
Session timing overrides inherit any fields omitted from `setup.session`.
|
||||
Token timing settings belong to each product independently.
|
||||
|
||||
Use `pytest tests\setup -s` to run all enabled products. Each product runs in its
|
||||
own browser: both flags true runs session then the product's token flow in one login; otherwise
|
||||
only its enabled action runs. Test/report names include the product name.
|
||||
Screenshot and log folders use the collected product and action, such as
|
||||
`IDAS_SESSION_TOKEN_001`, `RTM_TOKEN_001`, or `RTM_SESSION_001`.
|
||||
The shared HTML report for `tests\setup` uses `PXIL_SETUP_###.html`.
|
||||
Existing report folders retain their original names.
|
||||
The session and token subfolder commands below select only products configured
|
||||
for session-only and token-only respectively; use the full setup command for a
|
||||
mixture of modes.
|
||||
|
||||
Session and token together in one login:
|
||||
|
||||
```json
|
||||
@@ -69,7 +143,7 @@ Run only token setup:
|
||||
pytest tests\setup\tokens -s --html=reports/html/token_run.html --self-contained-html
|
||||
```
|
||||
|
||||
Use this when `run_token` is `true`. It will create one token or multiple tokens based on `trading_token_idas.product_codes`.
|
||||
Use this when `run_token` is `true`. It will create one token or multiple tokens based on `products.<product>.token.product_codes`.
|
||||
|
||||
Run only session setup:
|
||||
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"url": "https://utilseastern.pxil.in/Pxil/",
|
||||
"stagingurl": "https://utilseastern.pxil.in/Pxil/",
|
||||
"uaturl": "https://utilsuat.pxil.in/Pxil/",
|
||||
"login": {
|
||||
"username": "Tejas",
|
||||
"password": "Pxil@123"
|
||||
},
|
||||
"login_captcha_wait_seconds": 10,
|
||||
"login_captcha_max_retries": 10,
|
||||
"login_post_submit_wait_seconds": 10,
|
||||
"step_delay_seconds": 1,
|
||||
"setup": {
|
||||
"run_session": true,
|
||||
"run_token": false,
|
||||
"session": {
|
||||
"start_offset_minutes": 5,
|
||||
"end_time": "20:30"
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
"IDAS": {
|
||||
"enabled": true,
|
||||
"run_session": true,
|
||||
"run_token": false,
|
||||
"me_instance": "55",
|
||||
"session": {},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "IDAS",
|
||||
"product_code": "IDAS4",
|
||||
"product_codes": "IDAS,IDASTEST01,IDASTEST02,IDASTEST03,IDASTEST04,IDASTEST05,IDASTEST06",
|
||||
"available_codes": ",IDASTEST06,IDASTEST07,IDASTEST08,IDASTEST09,IDASTEST10,IDASTEST11,IDASTEST12,IDASTEST13,IDASTEST14,IDASTEST15,IDASTEST16,IDASTEST17,IDASTEST18,IDASTEST19,IDASTEST20,IDASTEST21,IDASTEST22,IDASTEST23,IDASTEST24,IDASTEST25,IDASTEST26,IDASTEST27,IDASTEST28,IDASTEST29,IDASTEST30",
|
||||
"delivery_offset_days": 1,
|
||||
"expiry_time": "20:30",
|
||||
"time_sessions": {
|
||||
"ORDER_NOR": {
|
||||
"start_offset_minutes": 10,
|
||||
"end_time": "19:30"
|
||||
},
|
||||
"ORDER_EXCH": {
|
||||
"start_time": "19:30",
|
||||
"end_time": "19:45"
|
||||
},
|
||||
"TRADE": {
|
||||
"start_time": "19:45",
|
||||
"end_time": "19:50"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"RTM": {
|
||||
"enabled": false,
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"me_instance": "52",
|
||||
"session": {
|
||||
"start_offset_minutes": 7,
|
||||
"end_time": "20:30"
|
||||
},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "RTM",
|
||||
"product_codes": [
|
||||
"RTM"
|
||||
],
|
||||
"generation_mode": "RTM",
|
||||
"delivery_offset_days": 0,
|
||||
"delivery_from_time": "00:00",
|
||||
"delivery_to_time": "23:59",
|
||||
"session_start_offset_minutes": 5,
|
||||
"session_end_time": "20:00"
|
||||
}
|
||||
},
|
||||
"UPC": {
|
||||
"enabled": true,
|
||||
"run_session": true,
|
||||
"run_token": true,
|
||||
"session_variants": {
|
||||
"DAILY": {
|
||||
"enabled": true,
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"me_instance": "58",
|
||||
"token": {
|
||||
"generation_mode": "AnyDayUPC",
|
||||
"create_product_codes": [
|
||||
"DailyC_E"
|
||||
],
|
||||
"available_product_codes": [
|
||||
"DailyC_D",
|
||||
"DailyGR_D",
|
||||
"DailyC_RTC",
|
||||
"DailyC_E",
|
||||
"DailyC_M"
|
||||
]
|
||||
}
|
||||
},
|
||||
"WEEKLY": {
|
||||
"enabled": true,
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"me_instance": "59",
|
||||
"token": {
|
||||
"generation_mode": "WeeklyUPC",
|
||||
"create_product_codes": [
|
||||
"WeeklyC_E"
|
||||
],
|
||||
"available_product_codes": [
|
||||
"WeeklyC_D",
|
||||
"WeeklyC_N",
|
||||
"WeeklyGR_D",
|
||||
"WeeklyC_RTC"
|
||||
]
|
||||
}
|
||||
},
|
||||
"MONTHLY": {
|
||||
"enabled": true,
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"me_instance": "60",
|
||||
"token": {
|
||||
"generation_mode": "MonthlyUPC",
|
||||
"create_product_codes": [
|
||||
"MonthlyC_N"
|
||||
],
|
||||
"available_product_codes": [
|
||||
"MonthlyC_D",
|
||||
"MonthlyGR_D",
|
||||
"MonthlyC_RTC"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"session": {},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "UPC",
|
||||
"product_codes": [],
|
||||
"delivery_offset_days": 1,
|
||||
"expiry_time": "20:30",
|
||||
"upc_times": {
|
||||
"order_normal_start_time": "13:00",
|
||||
"order_normal_end_time": "17:00",
|
||||
"trade_session_start_time": "17:00",
|
||||
"trade_session_end_time": "22:00"
|
||||
},
|
||||
"time_sessions": {
|
||||
"ORDER_NOR": {
|
||||
"start_offset_minutes": 10,
|
||||
"end_time": "19:30"
|
||||
},
|
||||
"ORDER_EXCH": {
|
||||
"start_time": "19:30",
|
||||
"end_time": "19:45"
|
||||
},
|
||||
"TRADE": {
|
||||
"start_time": "19:45",
|
||||
"end_time": "19:50"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"RA": {
|
||||
"enabled": false,
|
||||
"run_session": true,
|
||||
"run_token": false,
|
||||
"me_instance": "64",
|
||||
"session": {},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "RA",
|
||||
"product_codes": [],
|
||||
"delivery_offset_days": 1,
|
||||
"expiry_time": "20:30",
|
||||
"time_sessions": {}
|
||||
}
|
||||
},
|
||||
"REC": {
|
||||
"enabled": false,
|
||||
"run_session": true,
|
||||
"run_token": true,
|
||||
"me_instance": "25",
|
||||
"session": {},
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "REC",
|
||||
"product_codes": ["REC"],
|
||||
"delivery_offset_days": 1,
|
||||
"expiry_time": "20:30",
|
||||
"type_prefix": "REC",
|
||||
"time_sessions": {
|
||||
"ORDER_NOR": {
|
||||
"start_offset_minutes": 10,
|
||||
"end_time": "19:30"
|
||||
},
|
||||
"ORDER_EXCH": {
|
||||
"start_time": "19:30",
|
||||
"end_time": "19:45"
|
||||
},
|
||||
"TRADE": {
|
||||
"start_time": "19:45",
|
||||
"end_time": "19:50"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"url": "https://utilsuat.pxil.in/Pxil/",
|
||||
"stagingurl": "https://utilseastern.pxil.in/Pxil/",
|
||||
"uaturl": "https://utilsuat.pxil.in/Pxil/",
|
||||
"login": {
|
||||
"username": "Tejas",
|
||||
"password": "Pxil@123"
|
||||
},
|
||||
"product": {
|
||||
"me_instance": "55"
|
||||
},
|
||||
"login_captcha_wait_seconds": 10,
|
||||
"login_post_submit_wait_seconds": 10,
|
||||
"step_delay_seconds": 1,
|
||||
"setup": {
|
||||
"run_session": false,
|
||||
"run_token": true,
|
||||
"session": {
|
||||
"start_offset_minutes": 7,
|
||||
"end_time": "20:30"
|
||||
}
|
||||
},
|
||||
"trading_token_idas": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "IDAS",
|
||||
"product_code": "IDAS4",
|
||||
"product_codes": "IDAS,IDASTEST01,IDASTEST02,IDASTEST03,IDASTEST04,IDASTEST05,IDASTEST06",
|
||||
"available_codes":",IDASTEST06,IDASTEST07,IDASTEST08,IDASTEST09,IDASTEST10,IDASTEST11,IDASTEST12,IDASTEST13,IDASTEST14,IDASTEST15,IDASTEST16,IDASTEST17,IDASTEST18,IDASTEST19,IDASTEST20,IDASTEST21,IDASTEST22,IDASTEST23,IDASTEST24,IDASTEST25,IDASTEST26,IDASTEST27,IDASTEST28,IDASTEST29,IDASTEST30",
|
||||
"delivery_offset_days": 1,
|
||||
"expiry_time": "20:30",
|
||||
"time_sessions": {
|
||||
"ORDER_NOR": {
|
||||
"start_offset_minutes": 5,
|
||||
"end_time": "19:30"
|
||||
},
|
||||
"ORDER_EXCH": {
|
||||
"start_time": "19:30",
|
||||
"end_time": "19:45"
|
||||
},
|
||||
"TRADE": {
|
||||
"start_time": "19:45",
|
||||
"end_time": "19:50"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,3 +28,25 @@ In `runtime.json`:
|
||||
- `IDAS`, `RTM`, and future top-level product sections: product-wise defaults, available codes, supported flows, bidding config, matching config, and future product-specific controls.
|
||||
|
||||
Regression config now lives entirely inside `runtime.json`.
|
||||
|
||||
## UPC session setup
|
||||
|
||||
Session creation uses the root `config.json`, independently of regression settings.
|
||||
Set `products.UPC.enabled` to `true` to include UPC. Under
|
||||
`products.UPC.session_variants`, enable all three variants or only the ones required:
|
||||
|
||||
| Variant | ME instance ID | UI name |
|
||||
| --- | --- | --- |
|
||||
| DAILY | 58 | UPC ANYDAY |
|
||||
| WEEKLY | 59 | UPC WEEKLY |
|
||||
| MONTHLY | 60 | UPC MONTHLY |
|
||||
|
||||
Each variant has an `enabled` flag. UPC remains disabled by default; all three
|
||||
variants are preselected for when it is enabled. Set `UPC.run_session` and
|
||||
`UPC.run_token` to `true` when both session and token creation are required. Each selected variant uses the
|
||||
existing session creation flow and inherits `setup.session.start_offset_minutes`
|
||||
and `setup.session.end_time`. Optional `UPC.session` settings override those
|
||||
defaults, and a variant's `session` settings can override them individually.
|
||||
|
||||
Run session-only setup with `python -m pytest tests/setup/sessions/test_session.py`.
|
||||
Selected UPC cases appear as `UPC_DAILY`, `UPC_WEEKLY`, and `UPC_MONTHLY`.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import json
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -11,6 +12,80 @@ def load_config():
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def get_product_config(product_name, config=None):
|
||||
"""Resolve a product's setup flags and session defaults without mutating input."""
|
||||
config = deepcopy(load_config() if config is None else config)
|
||||
if "products" not in config:
|
||||
if product_name != "IDAS":
|
||||
raise ValueError(f"Unknown setup product: {product_name}")
|
||||
config["token"] = config.get("trading_token_idas", {})
|
||||
else:
|
||||
product = config["products"][product_name]
|
||||
setup = config.setdefault("setup", {})
|
||||
for flag in ("run_session", "run_token"):
|
||||
setup[flag] = product.get(flag, setup.get(flag, True))
|
||||
if not isinstance(setup[flag], bool):
|
||||
raise ValueError(f"products.{product_name}.{flag} must be true or false")
|
||||
setup["session"] = {**setup.get("session", {}), **product.get("session", {})}
|
||||
config["product"] = {"me_instance": product.get("me_instance")}
|
||||
config["token"] = deepcopy(product.get("token", {}))
|
||||
config["product_name"] = product_name
|
||||
return config
|
||||
|
||||
|
||||
def get_setup_configs(mode, config=None):
|
||||
"""Partition products so a full setup run never creates a product twice."""
|
||||
if mode not in ("combined", "session", "token"):
|
||||
raise ValueError(f"Unknown setup mode: {mode}")
|
||||
config = load_config() if config is None else config
|
||||
products = config.get("products", {"IDAS": {}})
|
||||
selected = []
|
||||
for name, product in products.items():
|
||||
if not product.get("enabled", True):
|
||||
continue
|
||||
variants = product.get("session_variants")
|
||||
if variants is not None:
|
||||
resolved = get_product_config(name, config)
|
||||
# Expand variants when either session or token execution is
|
||||
# enabled. Token-only UPC runs must still reach their variants.
|
||||
setup = resolved.get("setup", {})
|
||||
if not setup.get("run_session", True) and not setup.get("run_token", True):
|
||||
continue
|
||||
variant_config = deepcopy(config)
|
||||
variant_config["products"] = {}
|
||||
for variant_name, variant in variants.items():
|
||||
settings = deepcopy(product)
|
||||
settings.pop("session_variants")
|
||||
settings.update(variant)
|
||||
settings["session"] = {**product.get("session", {}), **variant.get("session", {})}
|
||||
settings["token"] = {**product.get("token", {}), **variant.get("token", {})}
|
||||
variant_config["products"][f"{name}_{variant_name}"] = settings
|
||||
selected.extend(get_setup_configs(mode, variant_config))
|
||||
continue
|
||||
resolved = get_product_config(name, config)
|
||||
setup = resolved.get("setup", {})
|
||||
session = setup.get("run_session", True)
|
||||
token = setup.get("run_token", True)
|
||||
matches = {
|
||||
"combined": session and token or (name.startswith("UPC_") and token),
|
||||
"session": session and not token,
|
||||
"token": token and not session,
|
||||
}
|
||||
if not matches[mode]:
|
||||
continue
|
||||
if session and not resolved.get("product", {}).get("me_instance"):
|
||||
raise ValueError(f"products.{name}.me_instance is required for session creation")
|
||||
if token:
|
||||
settings = resolved["token"]
|
||||
if not settings.get("market_code") or not (
|
||||
parse_product_codes(settings.get("create_product_codes", settings.get("product_codes")))
|
||||
or parse_product_codes(settings.get("product_code"))
|
||||
):
|
||||
raise ValueError(f"products.{name}.token requires market_code and product_code(s)")
|
||||
selected.append(resolved)
|
||||
return selected
|
||||
|
||||
|
||||
def get_step_delay_seconds(default=5):
|
||||
|
||||
config = load_config()
|
||||
|
||||
+33
-10
@@ -5,15 +5,15 @@ import json
|
||||
from tests.browser import create_chrome_driver
|
||||
|
||||
|
||||
def get_run_id(config):
|
||||
def get_run_id(config, prefix=None):
|
||||
|
||||
run_id = getattr(config, "_pxil_run_id", None)
|
||||
if run_id:
|
||||
return run_id
|
||||
run_prefix = prefix or _get_run_prefix(config)
|
||||
run_ids = getattr(config, "_pxil_run_ids", {})
|
||||
if run_prefix in run_ids:
|
||||
return run_ids[run_prefix]
|
||||
|
||||
base_folder = os.path.join("reports", "screenshots")
|
||||
os.makedirs(base_folder, exist_ok=True)
|
||||
run_prefix = _get_run_prefix(config)
|
||||
|
||||
existing = [
|
||||
name for name in os.listdir(base_folder)
|
||||
@@ -28,10 +28,11 @@ def get_run_id(config):
|
||||
for name in existing
|
||||
if name.split("_")[-1].isdigit()
|
||||
]
|
||||
next_number = max(numbers) + 1
|
||||
next_number = max(numbers, default=0) + 1
|
||||
|
||||
run_id = f"{run_prefix}_{next_number:03d}"
|
||||
config._pxil_run_id = run_id
|
||||
run_ids[run_prefix] = run_id
|
||||
config._pxil_run_ids = run_ids
|
||||
return run_id
|
||||
|
||||
|
||||
@@ -49,7 +50,7 @@ def pytest_configure(config):
|
||||
# -----------------------------
|
||||
# WebDriver Fixture
|
||||
# -----------------------------
|
||||
@pytest.fixture
|
||||
@pytest.fixture(scope="module")
|
||||
def driver():
|
||||
|
||||
driver = create_chrome_driver()
|
||||
@@ -66,7 +67,7 @@ def driver():
|
||||
@pytest.fixture
|
||||
def test_context(request):
|
||||
|
||||
test_id = get_run_id(request.config)
|
||||
test_id = get_run_id(request.config, _setup_item_prefix(request.node))
|
||||
test_name = request.node.name
|
||||
|
||||
folder = os.path.abspath(
|
||||
@@ -201,9 +202,28 @@ def _build_steps_html(steps):
|
||||
)
|
||||
|
||||
|
||||
def _setup_item_prefix(item):
|
||||
"""Use the collected product and flow, including when -k selects a subset."""
|
||||
nodeid = item.nodeid.replace("\\", "/")
|
||||
if "tests/setup/" not in nodeid:
|
||||
return None
|
||||
callspec = getattr(item, "callspec", None)
|
||||
product_config = callspec.params.get("config") if callspec else None
|
||||
if not isinstance(product_config, dict):
|
||||
return None
|
||||
product = product_config["product_name"].upper()
|
||||
if "test_combined_setup.py" in nodeid:
|
||||
return f"{product}_SESSION_TOKEN"
|
||||
if "/sessions/" in nodeid:
|
||||
return f"{product}_SESSION"
|
||||
if "/tokens/" in nodeid:
|
||||
return f"{product}_TOKEN"
|
||||
return f"{product}_SETUP"
|
||||
|
||||
|
||||
def _get_run_prefix(config):
|
||||
|
||||
invocation_args = " ".join(str(arg) for arg in config.invocation_params.args).lower()
|
||||
invocation_args = " ".join(str(arg) for arg in config.invocation_params.args).replace("\\", "/").lower()
|
||||
|
||||
if "tests/setup/sessions" in invocation_args or "test_session.py" in invocation_args:
|
||||
return "PXIL_SESSION"
|
||||
@@ -211,6 +231,9 @@ def _get_run_prefix(config):
|
||||
if "tests/setup/tokens" in invocation_args or "test_trading_token.py" in invocation_args:
|
||||
return "PXIL_TOKEN"
|
||||
|
||||
if "tests/setup" in invocation_args or "test_combined_setup.py" in invocation_args:
|
||||
return "PXIL_SETUP"
|
||||
|
||||
runtime_path = os.path.abspath(os.path.join("config", "runtime.json"))
|
||||
if os.path.exists(runtime_path):
|
||||
try:
|
||||
|
||||
+9
-3
@@ -367,7 +367,7 @@ def type_into_field(driver, locator, value):
|
||||
field.send_keys(value)
|
||||
|
||||
|
||||
def select_bootstrap_dropdown_by_id(driver, element_id, value):
|
||||
def select_bootstrap_dropdown_by_id(driver, element_id, value, exact=False):
|
||||
|
||||
wait = WebDriverWait(driver, 20)
|
||||
|
||||
@@ -411,12 +411,18 @@ def select_bootstrap_dropdown_by_id(driver, element_id, value):
|
||||
search_box.clear()
|
||||
search_box.send_keys(value)
|
||||
|
||||
option_xpath = (
|
||||
f"//div[@id='{element_id}']//div[contains(@class,'ui-select-choices-row')]"
|
||||
f"[normalize-space()='{value}']"
|
||||
if exact else
|
||||
"//div[contains(@class,'ui-select-choices-row')]"
|
||||
f"//*[normalize-space()='{value}' or starts-with(normalize-space(),'{value}')]"
|
||||
)
|
||||
option = wait.until(
|
||||
EC.element_to_be_clickable(
|
||||
(
|
||||
By.XPATH,
|
||||
"//div[contains(@class,'ui-select-choices-row')]"
|
||||
f"//*[normalize-space()='{value}' or starts-with(normalize-space(),'{value}')]"
|
||||
option_xpath
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -11,9 +11,18 @@ class Locator(object):
|
||||
tradingmaintenance="//span[normalize-space()='TRADING MAINTENANCE']"
|
||||
tradingsession="//a[normalize-space()='Trading Session Master']"
|
||||
tokengeneration="//a[@href='#/tradingMaintenance/generateToken' or normalize-space()='Token Generation']"
|
||||
tokengenerator = "//a[@href='#/tradingMaintenance/tokenGenerator']"
|
||||
generatormarketcode = "marketCode"
|
||||
generatorproductcode = "productCode"
|
||||
generatorgenerationmode = "tokenMstr.genMode"
|
||||
rtmdeliveryfromdate = "//div[@ng-show='showgeneration4']//input[@placeholder='Delivery From Date']"
|
||||
rtmdeliverytodate = "//div[@ng-show='showgeneration4']//input[@placeholder='Delivery To Date']"
|
||||
rtmsessionstarttime = "//div[@ng-show='showgeneration4']//input[@placeholder='Session Start Time']"
|
||||
rtmsessionendtime = "//div[@ng-show='showgeneration4']//input[@placeholder='Session End Time']"
|
||||
tokenandtimesessionview="//a[@href='#/tradingMaintenance/tokenTimeSessionMap' or normalize-space()='Token and Time Session View']"
|
||||
addsessionbtn="//button[contains(text(),'Add')]"
|
||||
addnewtokenbtn="//button[@data-ng-click='addToken()' and normalize-space()='Add New Token']"
|
||||
tokengeneratorresetbtn = "//button[@data-ng-click='refresh()' and normalize-space()='Reset']"
|
||||
setmeinstance="//span[@aria-label='meInstanceId activate']"
|
||||
#inputmeid="meInstanceId activate"
|
||||
#"//li[@id='ui-select-choices-178']"
|
||||
@@ -27,6 +36,16 @@ class Locator(object):
|
||||
tokendeliverystartdate = "//input[@placeholder='DELIVERY_START_DATE']"
|
||||
tokendeliveryenddate = "//input[@placeholder='DELIVERY_END_DATE']"
|
||||
tokenexpirydate = "//input[@placeholder='Token Expiry Date']"
|
||||
tokentype = "//input[@name='TYPE' or @placeholder='TYPE']"
|
||||
tokentradedate = "//input[@placeholder='Trade Date']"
|
||||
upcordernormalstart = "//input[@name='ses3StartTime']"
|
||||
upcordernormalend = "//input[@name='ses3EndTime']"
|
||||
upctradesessionstart = "//input[@name='sesStartTime']"
|
||||
upctradesessionend = "//input[@name='sesEndTime']"
|
||||
upcorderstart = "//input[@placeholder='Order Normal Start Time']"
|
||||
upcorderend = "//input[@placeholder='Order Normal End Time']"
|
||||
upctradestart = "//input[@placeholder='Trade Start Time' or @placeholder='Trade Session Start Time']"
|
||||
upctradeend = "//input[@placeholder='Trade End Time' or @placeholder='Trade Session End Time']"
|
||||
savetokenbtn = "//button[@data-ng-click='saveToken()' and normalize-space()='save Token']"
|
||||
tokentimesessionbtn = "//button[@data-ng-click='redirectToTimeSession()' and normalize-space()='Time Session']"
|
||||
viewproducttype = "pmProductType"
|
||||
|
||||
@@ -5,17 +5,11 @@ from selenium.webdriver.support.ui import WebDriverWait
|
||||
import pytest
|
||||
|
||||
from tests.step_actions import StepActions
|
||||
from tests.helpers import login, select_ui_dropdown
|
||||
from tests.config_reader import is_combined_setup_enabled, is_setup_session_enabled, load_config
|
||||
from tests.helpers import login, select_ui_dropdown, open_trading_maintenance_page
|
||||
from tests.config_reader import get_setup_configs
|
||||
from tests.locators import Locator
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
is_combined_setup_enabled() or not is_setup_session_enabled(),
|
||||
reason="Standalone session setup is disabled or runs inside combined setup",
|
||||
)
|
||||
|
||||
|
||||
def get_session_window(config):
|
||||
|
||||
session_config = config.get("setup", {}).get("session", {})
|
||||
@@ -30,9 +24,8 @@ def get_session_window(config):
|
||||
|
||||
def create_session(driver, step, config):
|
||||
|
||||
step.click((By.XPATH, Locator.tradingmaintenance), "trading_maintenance")
|
||||
|
||||
step.click((By.XPATH, Locator.tradingsession), "trading_session")
|
||||
open_trading_maintenance_page(driver, Locator.tradingsession)
|
||||
step.capture("trading_session")
|
||||
|
||||
step.click((By.XPATH, Locator.addsessionbtn), "add_session")
|
||||
|
||||
@@ -50,9 +43,8 @@ def create_session(driver, step, config):
|
||||
|
||||
|
||||
@pytest.mark.session
|
||||
def test_session(driver, test_context):
|
||||
|
||||
config = load_config()
|
||||
@pytest.mark.parametrize("config", get_setup_configs("session"), ids=lambda c: c["product_name"])
|
||||
def test_session(driver, test_context, config):
|
||||
|
||||
wait = WebDriverWait(driver, 20)
|
||||
|
||||
|
||||
@@ -1,46 +1,38 @@
|
||||
import pytest
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from tests.config_reader import is_combined_setup_enabled, load_config
|
||||
from tests.config_reader import get_setup_configs
|
||||
from tests.helpers import login, logout, save_session_backup
|
||||
from tests.setup.sessions.test_session import create_session
|
||||
from tests.setup.tokens.test_trading_token import create_and_activate_token, get_product_codes
|
||||
from tests.setup.tokens.test_trading_token import run_token_setup, get_product_codes
|
||||
from tests.step_actions import StepActions
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not is_combined_setup_enabled(),
|
||||
reason="Combined setup requires setup.run_session and setup.run_token to both be true",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.session
|
||||
@pytest.mark.trading_token
|
||||
def test_session_and_token_setup(driver, test_context):
|
||||
@pytest.mark.parametrize("config", get_setup_configs("combined"), ids=lambda c: c["product_name"])
|
||||
def test_session_and_token_setup(driver, test_context, config):
|
||||
|
||||
config = load_config()
|
||||
token = config.get("trading_token_idas")
|
||||
assert token, "Add trading_token_idas in config.json before running token setup."
|
||||
token = config["token"]
|
||||
|
||||
wait = WebDriverWait(driver, 20)
|
||||
step = StepActions(driver, wait, test_context)
|
||||
|
||||
driver.get(config["url"])
|
||||
step.capture("open_application")
|
||||
if not getattr(driver, "_pxil_logged_in", False):
|
||||
driver.get(config["url"])
|
||||
step.capture("open_application")
|
||||
|
||||
login(
|
||||
driver,
|
||||
config["login"]["username"],
|
||||
config["login"]["password"]
|
||||
)
|
||||
step.capture("login")
|
||||
save_session_backup(driver, test_context, "login_session_backup")
|
||||
if not getattr(driver, "_pxil_logged_in", False):
|
||||
login(driver, config["login"]["username"], config["login"]["password"])
|
||||
driver._pxil_logged_in = True
|
||||
step.capture("login")
|
||||
save_session_backup(driver, test_context, "login_session_backup")
|
||||
|
||||
create_session(driver, step, config)
|
||||
if config.get("setup", {}).get("run_session", True):
|
||||
create_session(driver, step, config)
|
||||
|
||||
for product_code in get_product_codes(token):
|
||||
product_token = dict(token)
|
||||
product_token["product_code"] = product_code
|
||||
create_and_activate_token(driver, step, product_token)
|
||||
run_token_setup(driver, step, product_token)
|
||||
|
||||
logout(driver)
|
||||
|
||||
@@ -3,8 +3,9 @@ from datetime import datetime, timedelta
|
||||
import pytest
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
from tests.config_reader import is_combined_setup_enabled, is_setup_token_enabled, load_config, parse_product_codes
|
||||
from tests.config_reader import get_setup_configs, parse_product_codes
|
||||
from tests.helpers import (
|
||||
click_visible_menu_item,
|
||||
click_first_grid_button,
|
||||
@@ -23,20 +24,10 @@ from tests.locators import Locator
|
||||
from tests.step_actions import StepActions
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
is_combined_setup_enabled() or not is_setup_token_enabled(),
|
||||
reason="Standalone token setup is disabled or runs inside combined setup",
|
||||
)
|
||||
|
||||
|
||||
def get_token_context(driver, test_context):
|
||||
|
||||
config = load_config()
|
||||
def get_token_context(driver, test_context, config):
|
||||
wait = WebDriverWait(driver, 20)
|
||||
step = StepActions(driver, wait, test_context)
|
||||
token = config.get("trading_token_idas")
|
||||
|
||||
assert token, "Add trading_token_idas in config.json before running this test."
|
||||
token = config["token"]
|
||||
|
||||
return config, step, token
|
||||
|
||||
@@ -83,12 +74,12 @@ def get_time_session_times(token, row_text, default_start_time, default_end_time
|
||||
|
||||
def get_product_codes(token):
|
||||
|
||||
product_codes = parse_product_codes(token.get("product_codes"))
|
||||
product_codes = parse_product_codes(token.get("create_product_codes", token.get("product_codes")))
|
||||
if product_codes:
|
||||
return product_codes
|
||||
|
||||
product_code = token.get("product_code")
|
||||
assert product_code, "Add product_code or product_codes in config.json trading_token_idas."
|
||||
assert product_code, "Add product_code or product_codes in config.json products.<product>.token."
|
||||
return parse_product_codes(product_code)
|
||||
|
||||
|
||||
@@ -143,11 +134,11 @@ def complete_time_session_edits(driver, step, token, next_day):
|
||||
edit_time_session_row(
|
||||
driver,
|
||||
step,
|
||||
"ORDER_NOR",
|
||||
"ORDER_NORMAL",
|
||||
order_nor_start_time,
|
||||
order_nor_end_time
|
||||
)
|
||||
edit_time_session_row(driver, step, "ORDER_EXCH", order_exch_start_time, order_exch_end_time)
|
||||
edit_time_session_row(driver, step, "ORDER_EXCHANGE", order_exch_start_time, order_exch_end_time)
|
||||
edit_time_session_row(driver, step, "TRADE", trade_start_time, trade_end_time)
|
||||
|
||||
click_first_grid_button(driver, "Token Details")
|
||||
@@ -160,6 +151,7 @@ def complete_time_session_edits(driver, step, token, next_day):
|
||||
def complete_time_session_edits_from_saved_token(driver, step, token):
|
||||
|
||||
step.click((By.XPATH, Locator.tokentimesessionbtn), "open_time_session")
|
||||
WebDriverWait(driver, 20).until(EC.url_contains("timeSessionView"))
|
||||
click_first_grid_button(driver, "Time Session Details")
|
||||
step.capture("open_time_session_details")
|
||||
step.capture("before_edit_order_normal")
|
||||
@@ -176,11 +168,11 @@ def complete_time_session_edits_from_saved_token(driver, step, token):
|
||||
edit_time_session_row(
|
||||
driver,
|
||||
step,
|
||||
"ORDER_NOR",
|
||||
"ORDER_NORMAL",
|
||||
order_nor_start_time,
|
||||
order_nor_end_time
|
||||
)
|
||||
edit_time_session_row(driver, step, "ORDER_EXCH", order_exch_start_time, order_exch_end_time)
|
||||
edit_time_session_row(driver, step, "ORDER_EXCHANGE", order_exch_start_time, order_exch_end_time)
|
||||
edit_time_session_row(driver, step, "TRADE", trade_start_time, trade_end_time)
|
||||
|
||||
click_first_grid_button(driver, "Token Details")
|
||||
@@ -190,6 +182,87 @@ def complete_time_session_edits_from_saved_token(driver, step, token):
|
||||
pause_after_step()
|
||||
|
||||
|
||||
def open_rtm_new_token(driver, step, token):
|
||||
"""Prepare the RTM generator through Add New Token."""
|
||||
open_trading_maintenance_page(driver, Locator.tokengenerator)
|
||||
handle_transient_popups(driver)
|
||||
step.capture("open_token_generator_rtm")
|
||||
|
||||
for element_id, value, name in (
|
||||
(Locator.generatormarketcode, token["market_code"], "market_code"),
|
||||
(Locator.generatorproductcode, token["product_code"], "product_code"),
|
||||
(Locator.generatorgenerationmode, token["generation_mode"], "generation_mode"),
|
||||
):
|
||||
select_bootstrap_dropdown_by_id(driver, element_id, value, exact=True)
|
||||
step.capture(f"select_{name}_rtm")
|
||||
|
||||
# Product Type is populated by the application after selecting Product Code.
|
||||
step.click((By.XPATH, Locator.addnewtokenbtn), "click_add_new_token_rtm")
|
||||
|
||||
|
||||
def get_rtm_token_times(token, now=None):
|
||||
now = datetime.now() if now is None else now
|
||||
delivery_date = (now + timedelta(days=token.get("delivery_offset_days", 0))).strftime("%d/%m/%Y")
|
||||
return (
|
||||
f"{delivery_date} {token.get('delivery_from_time', '00:00')}",
|
||||
f"{delivery_date} {token.get('delivery_to_time', '23:59')}",
|
||||
(now + timedelta(minutes=token.get("session_start_offset_minutes", 5))).strftime("%H:%M"),
|
||||
token.get("session_end_time", "20:00"),
|
||||
)
|
||||
|
||||
|
||||
def create_rtm_token(driver, step, token):
|
||||
open_rtm_new_token(driver, step, token)
|
||||
values = get_rtm_token_times(token)
|
||||
fields = (
|
||||
(Locator.rtmdeliveryfromdate, "delivery_from_date"),
|
||||
(Locator.rtmdeliverytodate, "delivery_to_date"),
|
||||
(Locator.rtmsessionstarttime, "session_start_time"),
|
||||
(Locator.rtmsessionendtime, "session_end_time"),
|
||||
)
|
||||
for (locator, name), value in zip(fields, values):
|
||||
type_first_visible_input(driver, locator, value)
|
||||
step.capture(f"enter_{name}_rtm")
|
||||
step.click((By.XPATH, Locator.savetokenbtn), "save_token_rtm")
|
||||
handle_transient_popups(driver)
|
||||
|
||||
|
||||
def create_upc_token(driver, step, token):
|
||||
open_trading_maintenance_page(driver, Locator.tokengenerator)
|
||||
handle_transient_popups(driver)
|
||||
step.capture("open_token_generator_upc")
|
||||
fields = [(Locator.generatormarketcode, token["market_code"], "market_code"), (Locator.generatorproductcode, token["product_code"], "product_code")]
|
||||
if driver.find_elements(By.ID, Locator.generatorgenerationmode):
|
||||
fields.append((Locator.generatorgenerationmode, token["generation_mode"], "generation_mode"))
|
||||
for element_id, value, name in fields:
|
||||
select_bootstrap_dropdown_by_id(driver, element_id, value, exact=True)
|
||||
step.capture(f"select_{name}_upc")
|
||||
step.click((By.XPATH, Locator.addnewtokenbtn), "click_add_new_token_upc")
|
||||
timings = token.get("upc_times", {})
|
||||
for name, locator, value in (
|
||||
("order_normal_start", Locator.upcorderstart, timings.get("order_normal_start_time")),
|
||||
("order_normal_end", Locator.upcorderend, timings.get("order_normal_end_time")),
|
||||
("trade_start", Locator.upctradestart, timings.get("trade_session_start_time")),
|
||||
("trade_end", Locator.upctradeend, timings.get("trade_session_end_time")),
|
||||
):
|
||||
if value:
|
||||
type_first_visible_input(driver, locator, value)
|
||||
step.capture(f"enter_{name}_upc")
|
||||
step.click((By.XPATH, Locator.savetokenbtn), "save_token_upc")
|
||||
handle_transient_popups(driver)
|
||||
step.click((By.XPATH, Locator.tokengeneratorresetbtn), "reset_token_generator_upc")
|
||||
|
||||
|
||||
def run_token_setup(driver, step, token):
|
||||
if token.get("product_type", "").upper() == "UPC":
|
||||
create_upc_token(driver, step, token)
|
||||
return
|
||||
if token.get("product_type", "").upper() == "RTM":
|
||||
create_rtm_token(driver, step, token)
|
||||
else:
|
||||
create_and_activate_token(driver, step, token)
|
||||
|
||||
|
||||
def create_and_activate_token(driver, step, token):
|
||||
|
||||
product_code = token["product_code"]
|
||||
@@ -209,31 +282,73 @@ def create_and_activate_token(driver, step, token):
|
||||
select_labeled_ui_dropdown(driver, "PRODUCT CODE", product_code)
|
||||
step.capture(f"select_product_code_{product_code.lower()}")
|
||||
|
||||
generation_mode = token.get("generation_mode")
|
||||
if generation_mode:
|
||||
mode_elements = driver.find_elements(By.ID, Locator.generatorgenerationmode)
|
||||
if mode_elements:
|
||||
select_bootstrap_dropdown_by_id(driver, Locator.generatorgenerationmode, generation_mode, exact=True)
|
||||
step.capture(f"select_generation_mode_{product_code.lower()}")
|
||||
|
||||
step.click((By.XPATH, Locator.addnewtokenbtn), f"click_add_new_token_{product_code.lower()}")
|
||||
|
||||
next_day, token_expiry = get_delivery_date_and_expiry(token)
|
||||
|
||||
step.type((By.XPATH, Locator.tokendeliverystartdate), next_day, f"enter_delivery_start_date_{product_code.lower()}")
|
||||
step.type((By.XPATH, Locator.tokendeliveryenddate), next_day, f"enter_delivery_end_date_{product_code.lower()}")
|
||||
step.type((By.XPATH, Locator.tokenexpirydate), token_expiry, f"enter_token_expiry_date_{product_code.lower()}")
|
||||
if token.get("product_type", "").upper() == "REC":
|
||||
token_type_prefix = token.get("type_prefix", "REC")
|
||||
token_type = f"{token_type_prefix}-{datetime.now().strftime('%d%m%Y')}"
|
||||
step.type((By.XPATH, Locator.tokentype), token_type, f"enter_type_{product_code.lower()}")
|
||||
|
||||
if token.get("product_type", "").upper() == "UPC":
|
||||
today = datetime.now().strftime("%d/%m/%Y")
|
||||
if token.get("generation_mode") == "AnyDayUPC":
|
||||
step.type((By.XPATH, Locator.tokentradedate), today, f"enter_trade_date_{product_code.lower()}")
|
||||
timings = token.get("upc_times", {})
|
||||
normal_start = timings.get("order_normal_start_time")
|
||||
if normal_start is None and timings.get("order_normal_start_offset_minutes") is not None:
|
||||
normal_start = (datetime.now() + timedelta(minutes=timings["order_normal_start_offset_minutes"])).strftime("%H:%M")
|
||||
values = {
|
||||
Locator.upcordernormalstart: normal_start,
|
||||
Locator.upcordernormalend: timings.get("order_normal_end_time"),
|
||||
Locator.upctradesessionstart: timings.get("trade_session_start_time"),
|
||||
Locator.upctradesessionend: timings.get("trade_session_end_time"),
|
||||
}
|
||||
for locator, value in values.items():
|
||||
if value is None:
|
||||
continue
|
||||
type_first_visible_input(driver, locator, value)
|
||||
|
||||
if (
|
||||
token.get("generation_mode") not in ("WeeklyUPC", "MonthlyUPC")
|
||||
and token.get("product_type", "").upper() != "REC"
|
||||
):
|
||||
step.type((By.XPATH, Locator.tokendeliverystartdate), next_day, f"enter_delivery_start_date_{product_code.lower()}")
|
||||
step.type((By.XPATH, Locator.tokendeliveryenddate), next_day, f"enter_delivery_end_date_{product_code.lower()}")
|
||||
|
||||
if token.get("generation_mode") not in ("WeeklyUPC", "MonthlyUPC"):
|
||||
step.type((By.XPATH, Locator.tokenexpirydate), token_expiry, f"enter_token_expiry_date_{product_code.lower()}")
|
||||
|
||||
step.click((By.XPATH, Locator.savetokenbtn), f"save_token_{product_code.lower()}")
|
||||
handle_transient_popups(driver)
|
||||
|
||||
if token.get("product_type", "").upper() == "UPC":
|
||||
step.click((By.XPATH, Locator.tokengeneratorresetbtn), f"reset_token_generator_{product_code.lower()}")
|
||||
return
|
||||
|
||||
complete_time_session_edits_from_saved_token(driver, step, token)
|
||||
|
||||
|
||||
@pytest.mark.trading_token
|
||||
def test_trading_token_creation_idas(driver, test_context):
|
||||
@pytest.mark.parametrize("config", get_setup_configs("token"), ids=lambda c: c["product_name"])
|
||||
def test_trading_token_creation(driver, test_context, config):
|
||||
|
||||
config, step, token = get_token_context(driver, test_context)
|
||||
config, step, token = get_token_context(driver, test_context, config)
|
||||
open_app_and_login(driver, step, config)
|
||||
save_session_backup(driver, test_context, "login_session_backup")
|
||||
|
||||
for product_code in get_product_codes(token):
|
||||
product_token = dict(token)
|
||||
product_token["product_code"] = product_code
|
||||
create_and_activate_token(driver, step, product_token)
|
||||
run_token_setup(driver, step, product_token)
|
||||
|
||||
logout(driver)
|
||||
|
||||
@@ -241,7 +356,7 @@ def test_trading_token_creation_idas(driver, test_context):
|
||||
# @pytest.mark.trading_token
|
||||
# def test_trading_token_time_session_edit_idas(driver, test_context):
|
||||
#
|
||||
# config, step, token = get_token_context(driver, test_context)
|
||||
# config, step, token = get_token_context(driver, test_context, config)
|
||||
# open_app_and_login(driver, step, config)
|
||||
#
|
||||
# next_day, _ = get_delivery_date_and_expiry(token)
|
||||
|
||||
@@ -5,7 +5,7 @@ import pytest
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from .config_reader import load_config
|
||||
from .config_reader import get_product_config
|
||||
from .helpers import (
|
||||
clear_pending_console_input,
|
||||
click_page_body,
|
||||
@@ -23,7 +23,7 @@ from .step_actions import StepActions
|
||||
|
||||
def _bounce_token_generation(driver, step, config):
|
||||
|
||||
token = config["trading_token_idas"]
|
||||
token = config["token"]
|
||||
interactions = random.randint(2, 4)
|
||||
|
||||
open_trading_maintenance_page(driver, Locator.tokengeneration)
|
||||
@@ -67,7 +67,7 @@ def _bounce_trading_session(driver, step, config):
|
||||
@pytest.mark.fake_activity
|
||||
def test_random_fake_activity_no_save(driver, test_context):
|
||||
|
||||
config = load_config()
|
||||
config = get_product_config("IDAS")
|
||||
wait = WebDriverWait(driver, 20)
|
||||
step = StepActions(driver, wait, test_context)
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.conftest import _get_run_prefix, _setup_item_prefix, get_run_id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path,product,expected", [
|
||||
("tests/setup/test_combined_setup.py", "IDAS", "IDAS_SESSION_TOKEN"),
|
||||
("tests/setup/test_combined_setup.py", "RTM", "RTM_SESSION_TOKEN"),
|
||||
("tests/setup/tokens/test_trading_token.py", "RTM", "RTM_TOKEN"),
|
||||
("tests/setup/sessions/test_session.py", "RTM", "RTM_SESSION"),
|
||||
])
|
||||
def test_setup_artifacts_use_collected_product_and_flow(path, product, expected):
|
||||
item = SimpleNamespace(nodeid=f"{path}::test[{product}]", callspec=SimpleNamespace(
|
||||
params={"config": {"product_name": product}},
|
||||
))
|
||||
assert _setup_item_prefix(item) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", ["tests/setup", "tests\\setup", "tests/setup/test_combined_setup.py"])
|
||||
def test_setup_report_does_not_use_regression_config(path):
|
||||
config = SimpleNamespace(invocation_params=SimpleNamespace(args=(path, "-k", "RTM")))
|
||||
assert _get_run_prefix(config) == "PXIL_SETUP"
|
||||
|
||||
|
||||
def test_mixed_run_ids_are_cached_separately(tmp_path, monkeypatch):
|
||||
monkeypatch.chdir(tmp_path)
|
||||
(tmp_path / "reports/screenshots/RTM_TOKEN_004").mkdir(parents=True)
|
||||
config = SimpleNamespace()
|
||||
assert get_run_id(config, "RTM_TOKEN") == "RTM_TOKEN_005"
|
||||
assert get_run_id(config, "IDAS_SESSION_TOKEN") == "IDAS_SESSION_TOKEN_001"
|
||||
assert get_run_id(config, "RTM_TOKEN") == "RTM_TOKEN_005"
|
||||
@@ -0,0 +1,115 @@
|
||||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.config_reader import get_product_config, get_setup_configs
|
||||
|
||||
|
||||
@pytest.mark.parametrize("common_session", [False, True])
|
||||
@pytest.mark.parametrize("common_token", [False, True])
|
||||
@pytest.mark.parametrize("session_override", [None, False, True])
|
||||
@pytest.mark.parametrize("token_override", [None, False, True])
|
||||
def test_product_flags_inherit_or_override(common_session, common_token, session_override, token_override):
|
||||
product = {"me_instance": "55", "token": {"market_code": "NATIONAL", "product_codes": "TEST"}}
|
||||
if session_override is not None:
|
||||
product["run_session"] = session_override
|
||||
if token_override is not None:
|
||||
product["run_token"] = token_override
|
||||
config = {"setup": {"run_session": common_session, "run_token": common_token}, "products": {"RTM": product}}
|
||||
session = common_session if session_override is None else session_override
|
||||
token = common_token if token_override is None else token_override
|
||||
expected = "combined" if session and token else "session" if session else "token" if token else None
|
||||
for mode in ("combined", "session", "token"):
|
||||
assert len(get_setup_configs(mode, config)) == int(mode == expected)
|
||||
|
||||
|
||||
def test_mixed_products_defaults_and_no_mutation():
|
||||
config = {
|
||||
"setup": {"run_session": True, "run_token": False, "session": {"start_offset_minutes": 7, "end_time": "20:30"}},
|
||||
"products": {
|
||||
"IDAS": {"me_instance": "55", "session": {"end_time": "21:00"}},
|
||||
"RTM": {"run_session": False, "run_token": True, "token": {"market_code": "NATIONAL", "product_codes": ["RTM1"]}},
|
||||
"REC": {"enabled": False},
|
||||
"RA": {"run_session": False},
|
||||
},
|
||||
}
|
||||
original = deepcopy(config)
|
||||
assert [c["product_name"] for c in get_setup_configs("session", config)] == ["IDAS"]
|
||||
assert [c["product_name"] for c in get_setup_configs("token", config)] == ["RTM"]
|
||||
assert get_setup_configs("combined", config) == []
|
||||
resolved = get_product_config("IDAS", config)
|
||||
assert resolved["setup"]["session"] == {"start_offset_minutes": 7, "end_time": "21:00"}
|
||||
assert config == original
|
||||
|
||||
|
||||
def test_missing_required_settings_fail_before_browser_start():
|
||||
with pytest.raises(ValueError, match="me_instance"):
|
||||
get_setup_configs("session", {"setup": {"run_token": False}, "products": {"REC": {}}})
|
||||
with pytest.raises(ValueError, match="market_code"):
|
||||
get_setup_configs("token", {"setup": {"run_session": False}, "products": {"REC": {}}})
|
||||
|
||||
|
||||
def test_legacy_config_remains_supported():
|
||||
config = {"product": {"me_instance": "55"}, "trading_token_idas": {"market_code": "NATIONAL", "product_code": "IDAS4"}}
|
||||
assert get_setup_configs("combined", config)[0]["token"] == config["trading_token_idas"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("selected", [[], ["DAILY"], ["WEEKLY"], ["MONTHLY"], ["DAILY", "WEEKLY", "MONTHLY"]])
|
||||
def test_upc_session_selection_and_shared_timing(selected):
|
||||
config = {
|
||||
"setup": {"session": {"start_offset_minutes": 7, "end_time": "20:30"}},
|
||||
"products": {"UPC": {
|
||||
"run_session": True,
|
||||
"run_token": False,
|
||||
"session_variants": {
|
||||
name: {"enabled": name in selected, "me_instance": instance}
|
||||
for name, instance in (("DAILY", "58"), ("WEEKLY", "59"), ("MONTHLY", "60"))
|
||||
},
|
||||
}},
|
||||
}
|
||||
original = deepcopy(config)
|
||||
sessions = get_setup_configs("session", config)
|
||||
assert [c["product_name"] for c in sessions] == [f"UPC_{name}" for name in selected]
|
||||
ids = {"DAILY": "58", "WEEKLY": "59", "MONTHLY": "60"}
|
||||
assert [c["product"]["me_instance"] for c in sessions] == [ids[name] for name in selected]
|
||||
assert all(c["setup"]["session"] == config["setup"]["session"] for c in sessions)
|
||||
assert get_setup_configs("combined", config) == []
|
||||
assert get_setup_configs("token", config) == []
|
||||
assert config == original
|
||||
config["products"]["UPC"]["enabled"] = False
|
||||
assert get_setup_configs("session", config) == []
|
||||
|
||||
|
||||
def test_upc_token_only_expands_all_enabled_variants():
|
||||
config = {
|
||||
"setup": {"run_session": True, "run_token": True},
|
||||
"products": {
|
||||
"UPC": {
|
||||
"enabled": True,
|
||||
"run_session": False,
|
||||
"run_token": True,
|
||||
"token": {
|
||||
"market_code": "NATIONAL",
|
||||
"product_type": "UPC",
|
||||
"product_codes": [],
|
||||
},
|
||||
"session_variants": {
|
||||
name: {
|
||||
"enabled": True,
|
||||
"run_session": False,
|
||||
"run_token": True,
|
||||
"token": {"create_product_codes": [f"{name}_TOKEN"]},
|
||||
}
|
||||
for name in ("DAILY", "WEEKLY", "MONTHLY")
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
configs = get_setup_configs("token", config)
|
||||
|
||||
assert [item["product_name"] for item in configs] == [
|
||||
"UPC_DAILY",
|
||||
"UPC_WEEKLY",
|
||||
"UPC_MONTHLY",
|
||||
]
|
||||
@@ -0,0 +1,71 @@
|
||||
from unittest.mock import Mock
|
||||
from datetime import datetime
|
||||
|
||||
from tests.locators import Locator
|
||||
from tests.setup.tokens import test_trading_token as actions
|
||||
|
||||
|
||||
def test_rtm_saves_generator_token_without_idas_activation(monkeypatch):
|
||||
events = []
|
||||
monkeypatch.setattr(actions, "open_trading_maintenance_page", lambda driver, menu: events.append(menu))
|
||||
monkeypatch.setattr(actions, "handle_transient_popups", lambda driver: None)
|
||||
monkeypatch.setattr(
|
||||
actions, "select_bootstrap_dropdown_by_id",
|
||||
lambda driver, field, value, exact=False: events.append((field, value, exact)),
|
||||
)
|
||||
idas_flow = Mock()
|
||||
monkeypatch.setattr(actions, "create_and_activate_token", idas_flow)
|
||||
step = Mock()
|
||||
step.click.side_effect = lambda locator, name: events.append(locator[1])
|
||||
monkeypatch.setattr(actions, "get_rtm_token_times", lambda token: (
|
||||
"23/09/2026 00:00", "23/09/2026 23:59", "10:15", "20:00",
|
||||
))
|
||||
monkeypatch.setattr(actions, "type_first_visible_input", lambda driver, locator, value: events.append((locator, value)))
|
||||
|
||||
actions.run_token_setup(Mock(), step, {
|
||||
"product_type": "RTM", "market_code": "NATIONAL",
|
||||
"product_code": "RTM", "generation_mode": "RTM",
|
||||
})
|
||||
|
||||
assert events == [
|
||||
Locator.tokengenerator,
|
||||
("marketCode", "NATIONAL", True),
|
||||
("productCode", "RTM", True),
|
||||
("tokenMstr.genMode", "RTM", True),
|
||||
Locator.addnewtokenbtn,
|
||||
(Locator.rtmdeliveryfromdate, "23/09/2026 00:00"),
|
||||
(Locator.rtmdeliverytodate, "23/09/2026 23:59"),
|
||||
(Locator.rtmsessionstarttime, "10:15"),
|
||||
(Locator.rtmsessionendtime, "20:00"),
|
||||
Locator.savetokenbtn,
|
||||
]
|
||||
step.type.assert_not_called()
|
||||
idas_flow.assert_not_called()
|
||||
|
||||
|
||||
def test_idas_keeps_existing_creation_and_activation_flow(monkeypatch):
|
||||
idas_flow = Mock()
|
||||
rtm_flow = Mock()
|
||||
monkeypatch.setattr(actions, "create_and_activate_token", idas_flow)
|
||||
monkeypatch.setattr(actions, "open_rtm_new_token", rtm_flow)
|
||||
driver, step = Mock(), Mock()
|
||||
token = {"product_type": "IDAS", "product_code": "IDAS4"}
|
||||
|
||||
actions.run_token_setup(driver, step, token)
|
||||
|
||||
idas_flow.assert_called_once_with(driver, step, token)
|
||||
rtm_flow.assert_not_called()
|
||||
|
||||
|
||||
def test_rtm_token_timing_defaults_and_overrides():
|
||||
now = datetime(2026, 9, 23, 10, 58)
|
||||
assert actions.get_rtm_token_times({}, now) == (
|
||||
"23/09/2026 00:00", "23/09/2026 23:59", "11:03", "20:00",
|
||||
)
|
||||
assert actions.get_rtm_token_times({
|
||||
"delivery_offset_days": 1,
|
||||
"delivery_from_time": "01:30", "delivery_to_time": "22:00",
|
||||
"session_start_offset_minutes": 12, "session_end_time": "21:15",
|
||||
}, now) == (
|
||||
"24/09/2026 01:30", "24/09/2026 22:00", "11:10", "21:15",
|
||||
)
|
||||
Reference in New Issue
Block a user