Add manual and offset time modes #10

Merged
tejasshasane merged 1 commits from try-captcha-automation into development 2026-11-02 06:35:39 +01:00
3 changed files with 252 additions and 198 deletions
Showing only changes of commit eb8a831edb - Show all commits
+199 -187
View File
@@ -1,195 +1,207 @@
{ {
"url": "https://utilseastern.pxil.in/Pxil/", "url": "https://utilseastern.pxil.in/Pxil/",
"stagingurl": "https://utilseastern.pxil.in/Pxil/", "stagingurl": "https://utilseastern.pxil.in/Pxil/",
"uaturl": "https://utilsuat.pxil.in/Pxil/", "uaturl": "https://utilsuat.pxil.in/Pxil/",
"login": { "login": {
"username": "Tejas", "username": "Tejas",
"password": "Pxil@123" "password": "Pxil@123"
}, },
"login_captcha_wait_seconds": 10, "login_captcha_wait_seconds": 10,
"login_captcha_max_retries": 10, "login_captcha_max_retries": 10,
"login_post_submit_wait_seconds": 10, "login_post_submit_wait_seconds": 10,
"step_delay_seconds": 1, "step_delay_seconds": 1,
"setup": { "setup": {
"run_session": true, "run_session": true,
"run_token": false, "run_token": false,
"session": { "session": {
"start_offset_minutes": 5, "time_mode": "offset",
"end_time": "20:30" "start_offset_minutes": 5,
} "start_time": "14:30",
}, "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": { "products": {
"enabled": false, "IDAS": {
"run_session": false, "enabled": true,
"run_token": true, "run_session": true,
"me_instance": "52", "run_token": false,
"session": { "me_instance": "55",
"start_offset_minutes": 7, "session": {},
"end_time": "20:30" "token": {
}, "market_code": "NATIONAL",
"token": { "product_type": "IDAS",
"market_code": "NATIONAL", "product_code": "IDAS4",
"product_type": "RTM", "product_codes": "IDAS,IDASTEST01,IDASTEST02,IDASTEST03,IDASTEST04,IDASTEST05,IDASTEST06",
"product_codes": [ "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",
"RTM" "delivery_offset_days": 1,
], "expiry_time": "20:30",
"generation_mode": "RTM", "time_sessions": {
"delivery_offset_days": 0, "ORDER_NOR": {
"delivery_from_time": "00:00", "start_offset_minutes": 10,
"delivery_to_time": "23:59", "end_time": "19:30"
"session_start_offset_minutes": 5, },
"session_end_time": "20:00" "ORDER_EXCH": {
} "start_time": "19:30",
}, "end_time": "19:45"
"UPC": { },
"enabled": true, "TRADE": {
"run_session": true, "start_time": "19:45",
"run_token": true, "end_time": "19:50"
"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": { "RTM": {
"enabled": true, "enabled": false,
"run_session": false, "run_session": false,
"run_token": true, "run_token": true,
"me_instance": "59", "me_instance": "52",
"token": { "session": {
"generation_mode": "WeeklyUPC", "time_mode": "offset",
"create_product_codes": [ "start_offset_minutes": 7,
"WeeklyC_E" "start_time": "14:30",
], "end_time": "20:30"
"available_product_codes": [ },
"WeeklyC_D", "token": {
"WeeklyC_N", "market_code": "NATIONAL",
"WeeklyGR_D", "product_type": "RTM",
"WeeklyC_RTC" "product_codes": [
] "RTM"
} ],
"generation_mode": "RTM",
"delivery_offset_days": 0,
"delivery_from_time": "00:00",
"delivery_to_time": "23:59",
"time_mode": "offset",
"session_start_offset_minutes": 5,
"session_start_time": "14:30",
"session_end_time": "20:00"
}
}, },
"MONTHLY": { "UPC": {
"enabled": true, "enabled": true,
"run_session": false, "run_session": true,
"run_token": true, "run_token": true,
"me_instance": "60", "session_variants": {
"token": { "DAILY": {
"generation_mode": "MonthlyUPC", "enabled": true,
"create_product_codes": [ "run_session": false,
"MonthlyC_N" "run_token": true,
], "me_instance": "58",
"available_product_codes": [ "token": {
"MonthlyC_D", "generation_mode": "AnyDayUPC",
"MonthlyGR_D", "create_product_codes": [
"MonthlyC_RTC" "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": {
"time_mode": "manual",
"order_normal_start_time": "13:00",
"order_normal_start_offset_minutes": 10,
"order_normal_end_time": "17:00",
"trade_session_start_time": "17:00",
"trade_session_end_time": "22:00"
}
}
},
"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": {
"time_mode": "offset",
"start_offset_minutes": 10,
"start_time": "14:30",
"end_time": "19:30"
},
"ORDER_EXCH": {
"start_time": "19:30",
"end_time": "19:45"
},
"TRADE": {
"start_time": "19:45",
"end_time": "19:50"
}
}
}
} }
},
"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"
}
}
},
"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"
}
}
}
} }
}
} }
+11 -3
View File
@@ -13,13 +13,21 @@ from tests.locators import Locator
def get_session_window(config): def get_session_window(config):
session_config = config.get("setup", {}).get("session", {}) session_config = config.get("setup", {}).get("session", {})
start_offset_minutes = session_config.get("start_offset_minutes", 7) time_mode = session_config.get("time_mode", "offset").lower()
if time_mode == "manual":
start_time = session_config.get("start_time")
if not start_time:
raise ValueError("Session time_mode 'manual' requires start_time")
elif time_mode == "offset":
start_offset_minutes = session_config.get("start_offset_minutes", 7)
start_time = (datetime.now() + timedelta(minutes=start_offset_minutes)).strftime("%H:%M")
else:
raise ValueError("Session time_mode must be 'manual' or 'offset'")
end_time = session_config.get("end_time", "20:30") end_time = session_config.get("end_time", "20:30")
start_datetime = datetime.now() + timedelta(minutes=start_offset_minutes)
today = datetime.now().strftime("%d/%m/%Y") today = datetime.now().strftime("%d/%m/%Y")
return start_datetime.strftime("%d/%m/%Y %H:%M"), f"{today} {end_time}" return f"{today} {start_time}", f"{today} {end_time}"
def create_session(driver, step, config): def create_session(driver, step, config):
+42 -8
View File
@@ -59,12 +59,16 @@ def get_delivery_date_and_expiry(token):
def get_time_session_times(token, row_text, default_start_time, default_end_time): def get_time_session_times(token, row_text, default_start_time, default_end_time):
time_session_config = token.get("time_sessions", {}).get(row_text, {}) time_session_config = token.get("time_sessions", {}).get(row_text, {})
time_mode = time_session_config.get("time_mode")
start_time = time_session_config.get("start_time") start_time = time_session_config.get("start_time")
if start_time is None: if time_mode == "offset":
start_offset_minutes = time_session_config.get("start_offset_minutes") start_offset_minutes = time_session_config.get("start_offset_minutes")
if start_offset_minutes is not None: if start_offset_minutes is None:
start_time = (datetime.now() + timedelta(minutes=start_offset_minutes)).strftime("%H:%M") raise ValueError(f"{row_text} offset mode requires start_offset_minutes")
start_time = (datetime.now() + timedelta(minutes=start_offset_minutes)).strftime("%H:%M")
elif time_mode == "manual" and not start_time:
raise ValueError(f"{row_text} manual mode requires start_time")
return ( return (
start_time or default_start_time, start_time or default_start_time,
@@ -72,6 +76,29 @@ def get_time_session_times(token, row_text, default_start_time, default_end_time
) )
def get_upc_order_normal_start_time(timings, now=None):
"""Resolve UPC order-normal start time from manual or offset mode."""
mode = timings.get("time_mode", "manual").lower()
if mode == "offset":
offset = timings.get("order_normal_start_offset_minutes")
if offset is None:
raise ValueError(
"UPC time_mode 'offset' requires "
"order_normal_start_offset_minutes"
)
now = datetime.now() if now is None else now
return (now + timedelta(minutes=offset)).strftime("%H:%M")
if mode != "manual":
raise ValueError("UPC time_mode must be 'manual' or 'offset'")
start_time = timings.get("order_normal_start_time")
if not start_time:
raise ValueError(
"UPC time_mode 'manual' requires order_normal_start_time"
)
return start_time
def get_product_codes(token): def get_product_codes(token):
product_codes = parse_product_codes(token.get("create_product_codes", token.get("product_codes"))) product_codes = parse_product_codes(token.get("create_product_codes", token.get("product_codes")))
@@ -203,10 +230,19 @@ def open_rtm_new_token(driver, step, token):
def get_rtm_token_times(token, now=None): def get_rtm_token_times(token, now=None):
now = datetime.now() if now is None else now now = datetime.now() if now is None else now
delivery_date = (now + timedelta(days=token.get("delivery_offset_days", 0))).strftime("%d/%m/%Y") delivery_date = (now + timedelta(days=token.get("delivery_offset_days", 0))).strftime("%d/%m/%Y")
time_mode = token.get("time_mode", "offset").lower()
if time_mode == "manual":
session_start_time = token.get("session_start_time")
if not session_start_time:
raise ValueError("RTM time_mode 'manual' requires session_start_time")
elif time_mode == "offset":
session_start_time = (now + timedelta(minutes=token.get("session_start_offset_minutes", 5))).strftime("%H:%M")
else:
raise ValueError("RTM time_mode must be 'manual' or 'offset'")
return ( return (
f"{delivery_date} {token.get('delivery_from_time', '00:00')}", f"{delivery_date} {token.get('delivery_from_time', '00:00')}",
f"{delivery_date} {token.get('delivery_to_time', '23:59')}", f"{delivery_date} {token.get('delivery_to_time', '23:59')}",
(now + timedelta(minutes=token.get("session_start_offset_minutes", 5))).strftime("%H:%M"), session_start_time,
token.get("session_end_time", "20:00"), token.get("session_end_time", "20:00"),
) )
@@ -240,7 +276,7 @@ def create_upc_token(driver, step, token):
step.click((By.XPATH, Locator.addnewtokenbtn), "click_add_new_token_upc") step.click((By.XPATH, Locator.addnewtokenbtn), "click_add_new_token_upc")
timings = token.get("upc_times", {}) timings = token.get("upc_times", {})
for name, locator, value in ( for name, locator, value in (
("order_normal_start", Locator.upcorderstart, timings.get("order_normal_start_time")), ("order_normal_start", Locator.upcorderstart, get_upc_order_normal_start_time(timings)),
("order_normal_end", Locator.upcorderend, timings.get("order_normal_end_time")), ("order_normal_end", Locator.upcorderend, timings.get("order_normal_end_time")),
("trade_start", Locator.upctradestart, timings.get("trade_session_start_time")), ("trade_start", Locator.upctradestart, timings.get("trade_session_start_time")),
("trade_end", Locator.upctradeend, timings.get("trade_session_end_time")), ("trade_end", Locator.upctradeend, timings.get("trade_session_end_time")),
@@ -303,9 +339,7 @@ def create_and_activate_token(driver, step, token):
if token.get("generation_mode") == "AnyDayUPC": if token.get("generation_mode") == "AnyDayUPC":
step.type((By.XPATH, Locator.tokentradedate), today, f"enter_trade_date_{product_code.lower()}") step.type((By.XPATH, Locator.tokentradedate), today, f"enter_trade_date_{product_code.lower()}")
timings = token.get("upc_times", {}) timings = token.get("upc_times", {})
normal_start = timings.get("order_normal_start_time") normal_start = get_upc_order_normal_start_time(timings)
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 = { values = {
Locator.upcordernormalstart: normal_start, Locator.upcordernormalstart: normal_start,
Locator.upcordernormalend: timings.get("order_normal_end_time"), Locator.upcordernormalend: timings.get("order_normal_end_time"),