Commit 5c6d0b9734f9df00c72b5fb61aa9cc5e75d008cb
Merge pull request #37 from selurvedu/periods_and_tender_data
Period intervals; initial tender data
Showing
22 changed files
with
289 additions
and
420 deletions
| 1 | -*** Setting *** | |
| 1 | +*** Settings *** | |
| 2 | 2 | Library Selenium2Screenshots |
| 3 | 3 | Library String |
| 4 | 4 | Library DateTime |
| 5 | +Library etender_service.py | |
| 5 | 6 | |
| 6 | 7 | *** Variables *** |
| 7 | 8 | ${locator.tenderId} jquery=h3 |
| ... | ... | @@ -44,7 +45,7 @@ ${locator.questions[0].answer} xpath=(//div[@tex |
| 44 | 45 | |
| 45 | 46 | Підготувати клієнт для користувача |
| 46 | 47 | [Arguments] @{ARGUMENTS} |
| 47 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 48 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 48 | 49 | ... ${ARGUMENTS[0]} == username |
| 49 | 50 | Open Browser ${USERS.users['${ARGUMENTS[0]}'].homepage} ${USERS.users['${username}'].browser} alias=${ARGUMENTS[0]} |
| 50 | 51 | Set Window Size @{USERS.users['${ARGUMENTS[0]}'].size} |
| ... | ... | @@ -63,8 +64,8 @@ Login |
| 63 | 64 | [Documentation] |
| 64 | 65 | ... ${ARGUMENTS[0]} == username |
| 65 | 66 | ... ${ARGUMENTS[1]} == tender_data |
| 66 | - ${INITIAL_TENDER_DATA}= procuringEntity_name ${INITIAL_TENDER_DATA} | |
| 67 | - ${tender_data}= Add_data_for_GUI_FrontEnds ${ARGUMENTS[1]} | |
| 67 | + ${tender_data}= Add_data_for_GUI_FrontEnds ${ARGUMENTS[1]} | |
| 68 | + ${tender_data}= procuring_entity_name ${tender_data} | |
| 68 | 69 | ${items}= Get From Dictionary ${tender_data.data} items |
| 69 | 70 | ${title}= Get From Dictionary ${tender_data.data} title |
| 70 | 71 | ${description}= Get From Dictionary ${tender_data.data} description |
| ... | ... | @@ -201,8 +202,7 @@ Set Multi Ids |
| 201 | 202 | ... ${ARGUMENTS[0]} == username |
| 202 | 203 | ... ${ARGUMENTS[1]} == ${TENDER_UAID} |
| 203 | 204 | Switch browser ${ARGUMENTS[0]} |
| 204 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 205 | - Go To ${url} | |
| 205 | + Go To ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 206 | 206 | Wait Until Page Contains Прозорі закупівлі 10 |
| 207 | 207 | sleep 1 |
| 208 | 208 | Input Text jquery=input[ng-change='searchChange()'] ${ARGUMENTS[1]} | ... | ... |
| 1 | +from iso8601 import parse_date | |
| 2 | + | |
| 3 | + | |
| 4 | +def convert_date_to_etender_format(isodate): | |
| 5 | + iso_dt = parse_date(isodate) | |
| 6 | + date_string = iso_dt.strftime("%d-%m-%Y") | |
| 7 | + return date_string | |
| 8 | + | |
| 9 | + | |
| 10 | +def convert_datetime_for_delivery(isodate): | |
| 11 | + iso_dt = parse_date(isodate) | |
| 12 | + date_string = iso_dt.strftime("%Y-%m-%d %H:%M") | |
| 13 | + return date_string | |
| 14 | + | |
| 15 | + | |
| 16 | +def convert_time_to_etender_format(isodate): | |
| 17 | + iso_dt = parse_date(isodate) | |
| 18 | + time_string = iso_dt.strftime("%H:%M") | |
| 19 | + return time_string | |
| 20 | + | |
| 21 | + | |
| 22 | +def procuring_entity_name(tender_data): | |
| 23 | + tender_data.data.procuringEntity['name'] = u"Повна назва невідомо чого" | |
| 24 | + return tender_data | ... | ... |
| 1 | -*** Setting *** | |
| 1 | +*** Settings *** | |
| 2 | 2 | Library Selenium2Screenshots |
| 3 | 3 | Library String |
| 4 | 4 | Library DateTime |
| 5 | +Library netcast_service.py | |
| 5 | 6 | |
| 6 | 7 | *** Variables *** |
| 7 | 8 | ${locator.tenderId} xpath=//td[./text()='TenderID']/following-sibling::td[1] |
| ... | ... | @@ -29,10 +30,12 @@ ${locator.questions[0].answer} xpath=//div[@class = 'answer relative']//di |
| 29 | 30 | *** Keywords *** |
| 30 | 31 | Підготувати клієнт для користувача |
| 31 | 32 | [Arguments] @{ARGUMENTS} |
| 32 | - [Documentation] Відкрити брaузер, створити обєкт api wrapper, тощо | |
| 33 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 33 | 34 | ... ${ARGUMENTS[0]} == username |
| 34 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 35 | - Open Browser ${url} ${USERS.users['${ARGUMENTS[0]}'].browser} alias=${ARGUMENTS[0]} | |
| 35 | + Open Browser | |
| 36 | + ... ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 37 | + ... ${USERS.users['${ARGUMENTS[0]}'].browser} | |
| 38 | + ... alias=${ARGUMENTS[0]} | |
| 36 | 39 | Set Window Size @{USERS.users['${ARGUMENTS[0]}'].size} |
| 37 | 40 | Set Window Position @{USERS.users['${ARGUMENTS[0]}'].position} |
| 38 | 41 | Run Keyword And Ignore Error Pre Login ${ARGUMENTS[0]} |
| ... | ... | @@ -53,7 +56,7 @@ Login |
| 53 | 56 | Pre Login |
| 54 | 57 | [Arguments] @{ARGUMENTS} |
| 55 | 58 | [Documentation] |
| 56 | - ... ${ARGUMENTS[0]} == username | |
| 59 | + ... ${ARGUMENTS[0]} == username | |
| 57 | 60 | ${login}= Get Broker Property By Username ${ARGUMENTS[0]} login |
| 58 | 61 | ${password}= Get Broker Property By Username ${ARGUMENTS[0]} password |
| 59 | 62 | Wait Until Page Contains Element name=siteLogin 10 |
| ... | ... | @@ -233,8 +236,7 @@ Set Multi Ids |
| 233 | 236 | ... ${ARGUMENTS[0]} == username |
| 234 | 237 | ... ${ARGUMENTS[1]} == tenderId |
| 235 | 238 | Switch browser ${ARGUMENTS[0]} |
| 236 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 237 | - Go To ${url} | |
| 239 | + Go To ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 238 | 240 | Wait Until Page Contains Держзакупівлі.онлайн 10 |
| 239 | 241 | Click Element xpath=//a[text()='Закупівлі'] |
| 240 | 242 | sleep 1 | ... | ... |
| 1 | -*** Setting *** | |
| 1 | +*** Settings *** | |
| 2 | 2 | Library Selenium2Screenshots |
| 3 | 3 | Library String |
| 4 | 4 | Library DateTime |
| 5 | +Library newtend_service.py | |
| 5 | 6 | |
| 6 | 7 | *** Variables *** |
| 7 | 8 | ${locator.title} xpath=//div[@ng-bind="tender.title"] |
| ... | ... | @@ -40,10 +41,12 @@ ${locator.QUESTIONS[0].date} xpath=//span[@class="date ng-binding"] |
| 40 | 41 | |
| 41 | 42 | Підготувати клієнт для користувача |
| 42 | 43 | [Arguments] @{ARGUMENTS} |
| 43 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 44 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 44 | 45 | ... ${ARGUMENTS[0]} == username |
| 45 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 46 | - Open Browser ${url} ${USERS.users['${username}'].browser} alias=${ARGUMENTS[0]} | |
| 46 | + Open Browser | |
| 47 | + ... ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 48 | + ... ${USERS.users['${ARGUMENTS[0]}'].browser} | |
| 49 | + ... alias=${ARGUMENTS[0]} | |
| 47 | 50 | Set Window Size @{USERS.users['${ARGUMENTS[0]}'].size} |
| 48 | 51 | Set Window Position @{USERS.users['${ARGUMENTS[0]}'].position} |
| 49 | 52 | Run Keyword If '${username}' != 'Newtend_Viewer' Login |
| ... | ... | @@ -63,20 +66,19 @@ Login |
| 63 | 66 | [Arguments] @{ARGUMENTS} |
| 64 | 67 | [Documentation] |
| 65 | 68 | ... ${ARGUMENTS[0]} == username |
| 66 | - ... ${ARGUMENTS[1]} == initial_tender_data | |
| 67 | -## Inicialisation | |
| 68 | - #${prepared_tender_data}= Add_data_for_GUI_FrontEnds ${ARGUMENTS[1]} | |
| 69 | - ${INITIAL_TENDER_DATA}= Add_data_for_GUI_FrontEnds ${INITIAL_TENDER_DATA} | |
| 70 | - ${INITIAL_TENDER_DATA}= Update_data_for_Newtend ${INITIAL_TENDER_DATA} | |
| 71 | - ${items}= Get From Dictionary ${INITIAL_TENDER_DATA.data} items | |
| 72 | - ${title}= Get From Dictionary ${INITIAL_TENDER_DATA.data} title | |
| 73 | - ${description}= Get From Dictionary ${INITIAL_TENDER_DATA.data} description | |
| 74 | - ${budget}= Get From Dictionary ${INITIAL_TENDER_DATA.data.value} amount | |
| 75 | - ${step_rate}= Get From Dictionary ${INITIAL_TENDER_DATA.data.minimalStep} amount | |
| 76 | - ${start_date}= Get From Dictionary ${INITIAL_TENDER_DATA.data.tenderPeriod} startDate | |
| 77 | - ${end_date}= Get From Dictionary ${INITIAL_TENDER_DATA.data.tenderPeriod} endDate | |
| 78 | - ${enquiry_start_date}= Get From Dictionary ${INITIAL_TENDER_DATA.data.enquiryPeriod} startDate | |
| 79 | - ${enquiry_end_date}= Get From Dictionary ${INITIAL_TENDER_DATA.data.enquiryPeriod} endDate | |
| 69 | + ... ${ARGUMENTS[1]} == tender_data | |
| 70 | +## Initialisation | |
| 71 | + ${prepared_tender_data}= Add_data_for_GUI_FrontEnds ${ARGUMENTS[1]} | |
| 72 | + ${prepared_tender_data}= Update_data_for_Newtend ${prepared_tender_data} | |
| 73 | + ${items}= Get From Dictionary ${prepared_tender_data.data} items | |
| 74 | + ${title}= Get From Dictionary ${prepared_tender_data.data} title | |
| 75 | + ${description}= Get From Dictionary ${prepared_tender_data.data} description | |
| 76 | + ${budget}= Get From Dictionary ${prepared_tender_data.data.value} amount | |
| 77 | + ${step_rate}= Get From Dictionary ${prepared_tender_data.data.minimalStep} amount | |
| 78 | + ${start_date}= Get From Dictionary ${prepared_tender_data.data.tenderPeriod} startDate | |
| 79 | + ${end_date}= Get From Dictionary ${prepared_tender_data.data.tenderPeriod} endDate | |
| 80 | + ${enquiry_start_date}= Get From Dictionary ${prepared_tender_data.data.enquiryPeriod} startDate | |
| 81 | + ${enquiry_end_date}= Get From Dictionary ${prepared_tender_data.data.enquiryPeriod} endDate | |
| 80 | 82 | |
| 81 | 83 | Selenium2Library.Switch Browser ${ARGUMENTS[0]} |
| 82 | 84 | Go To ${USERS.users['${username}'].homepage} | ... | ... |
| 1 | +from datetime import datetime | |
| 2 | +from iso8601 import parse_date | |
| 3 | +from calendar import monthrange | |
| 4 | + | |
| 5 | + | |
| 6 | +def newtend_date_picker_index(isodate): | |
| 7 | + now = datetime.today() | |
| 8 | + date_str = '01' + str(now.month) + str(now.year) | |
| 9 | + first_day_of_month = datetime.strptime(date_str, "%d%m%Y") | |
| 10 | + mod = first_day_of_month.isoweekday() - 2 | |
| 11 | + iso_dt = parse_date(isodate) | |
| 12 | + # last_day_of_month = monthrange(now.year, now.month)[1] | |
| 13 | + # LOGGER.log_message(Message("last_day_of_month: {}".format(last_day_of_month), "INFO")) | |
| 14 | + if now.day > iso_dt.day: | |
| 15 | + mod = monthrange(now.year, now.month)[1] + mod | |
| 16 | + return mod + iso_dt.day | |
| 17 | + | |
| 18 | + | |
| 19 | +def update_data_for_newtend(tender_data): | |
| 20 | + tender_data.data.procuringEntity['name'] = u"openprocurement" | |
| 21 | + return tender_data | ... | ... |
| ... | ... | @@ -22,7 +22,7 @@ Library Selenium2Screenshots |
| 22 | 22 | |
| 23 | 23 | Підготувати клієнт для користувача |
| 24 | 24 | [Arguments] @{ARGUMENTS} |
| 25 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 25 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 26 | 26 | ${api_wrapper}= prepare_api_wrapper ${USERS.users['${ARGUMENTS[0]}'].api_key} ${API_HOST_URL} ${api_version} |
| 27 | 27 | Set To Dictionary ${USERS.users['${ARGUMENTS[0]}']} client ${api_wrapper} |
| 28 | 28 | ${ID_MAP}= Create Dictionary |
| ... | ... | @@ -67,9 +67,9 @@ Library Selenium2Screenshots |
| 67 | 67 | [Documentation] |
| 68 | 68 | ... ${ARGUMENTS[0]} == username |
| 69 | 69 | ... ${ARGUMENTS[1]} == fieldname |
| 70 | - log ${ARGUMENTS} | |
| 71 | - ${field_value}= Get_From_Object ${USERS.users['${ARGUMENTS[0]}'].tender_data.data} ${ARGUMENTS[1]} | |
| 72 | - log ${field_value} | |
| 70 | + Log Many @{ARGUMENTS} | |
| 71 | + ${field_value}= Get_From_Object ${USERS.users['${ARGUMENTS[0]}'].tender_data.data} ${ARGUMENTS[1]} | |
| 72 | + Log ${field_value} | |
| 73 | 73 | [return] ${field_value} |
| 74 | 74 | |
| 75 | 75 | Внести зміни в тендер |
| ... | ... | @@ -104,11 +104,11 @@ Library Selenium2Screenshots |
| 104 | 104 | ... ${ARGUMENTS[2]} == number |
| 105 | 105 | ${internalid}= Отримати internal id по UAid ${ARGUMENTS[0]} ${ARGUMENTS[1]} |
| 106 | 106 | Отримати тендер ${ARGUMENTS[0]} ${internalid} |
| 107 | - ${items}= get from object ${TENDER_DATA.data} items | |
| 108 | - log ${items} | |
| 107 | + @{items}= Get From Object ${TENDER_DATA.data} items | |
| 108 | + Log Many @{items} | |
| 109 | 109 | :FOR ${INDEX} IN RANGE ${ARGUMENTS[2]} |
| 110 | 110 | \ Remove From List ${items} 0 |
| 111 | - log ${items} | |
| 111 | + Log Many @{items} | |
| 112 | 112 | Set_To_Object ${TENDER_DATA.data} items ${items} |
| 113 | 113 | ${TENDER_DATA}= Call Method ${USERS.users['${ARGUMENTS[0]}'].client} patch_tender ${TENDER_DATA} |
| 114 | 114 | ${TENDER_DATA}= set_access_key ${TENDER_DATA} ${USERS.users['${ARGUMENTS[0]}'].access_token} |
| ... | ... | @@ -121,12 +121,13 @@ Library Selenium2Screenshots |
| 121 | 121 | ... ${ARGUMENTS[2]} == number |
| 122 | 122 | ${internalid}= Отримати internal id по UAid ${ARGUMENTS[0]} ${ARGUMENTS[1]} |
| 123 | 123 | Отримати тендер ${ARGUMENTS[0]} ${internalid} |
| 124 | - ${items}= get from object ${TENDER_DATA.data} items | |
| 124 | + @{items}= Get From Object ${TENDER_DATA.data} items | |
| 125 | 125 | ${item}= get variable value ${items[1]} |
| 126 | - log ${items} | |
| 126 | + Run Keyword And Continue On Failure Remove From Dictionary ${item} id | |
| 127 | + Log Many @{items} | |
| 127 | 128 | :FOR ${INDEX} IN RANGE ${ARGUMENTS[2]} |
| 128 | 129 | \ Append To List ${items} ${item} |
| 129 | - log ${items} | |
| 130 | + Log Many @{items} | |
| 130 | 131 | Set_To_Object ${TENDER_DATA.data} items ${items} |
| 131 | 132 | ${TENDER_DATA}= set_access_key ${TENDER_DATA} ${USERS.users['${ARGUMENTS[0]}'].access_token} |
| 132 | 133 | ${TENDER_DATA}= Call Method ${USERS.users['${ARGUMENTS[0]}'].client} patch_tender ${TENDER_DATA} | ... | ... |
| ... | ... | @@ -20,9 +20,11 @@ ${PASSWORD} 1234 |
| 20 | 20 | [Arguments] ${username} |
| 21 | 21 | log many @{ARGUMENTS} |
| 22 | 22 | log ${username} |
| 23 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 24 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 25 | - Open Browser ${url} ${USERS.users['${username}'].browser} alias=${username} | |
| 23 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 24 | + Open Browser | |
| 25 | + ... ${USERS.users['${username}'].homepage} | |
| 26 | + ... ${USERS.users['${username}'].browser} | |
| 27 | + ... alias=${username} | |
| 26 | 28 | Set Window Position @{USERS.users['${username}'].position} |
| 27 | 29 | #Set Window Size @{USERS.users['${username}'].size} |
| 28 | 30 | Log Variables |
| ... | ... | @@ -46,11 +48,11 @@ Login |
| 46 | 48 | Login |
| 47 | 49 | |
| 48 | 50 | ${start_date}= Get From Dictionary ${ARGUMENTS[1].data.tenderPeriod} startDate |
| 49 | - ${start_date}= convert_date_to_prom_format ${start_date} | |
| 51 | + ${start_date}= convert_datetime_to_dot_format ${start_date} | |
| 50 | 52 | ${end_date}= Get From Dictionary ${ARGUMENTS[1].data.tenderPeriod} endDate |
| 51 | - ${end_date}= convert_date_to_prom_format ${end_date} | |
| 53 | + ${end_date}= convert_datetime_to_dot_format ${end_date} | |
| 52 | 54 | ${enquiry_end_date}= Get From Dictionary ${ARGUMENTS[1].data.enquiryPeriod} endDate |
| 53 | - ${enquiry_end_date}= convert_date_to_prom_format ${enquiry_end_date} | |
| 55 | + ${enquiry_end_date}= convert_datetime_to_dot_format ${enquiry_end_date} | |
| 54 | 56 | |
| 55 | 57 | ${items}= Get From Dictionary ${ARGUMENTS[1].data} items |
| 56 | 58 | ${delivery_date}= Get From Dictionary ${items[0].deliveryDate} endDate |
| ... | ... | @@ -100,9 +102,9 @@ Get tender id |
| 100 | 102 | ... ${ARGUMENTS[2]} == id |
| 101 | 103 | Switch browser ${ARGUMENTS[0]} |
| 102 | 104 | ${current_location}= Get Location |
| 103 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 104 | - Run Keyword If '${url}/#/tenderDetailes/${ARGUMENTS[2]}'=='${current_location}' Reload Page | |
| 105 | - Go to ${url} | |
| 105 | + ${homepage}= Set Variable ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 106 | + Run Keyword If '${homepage}/#/tenderDetailes/${ARGUMENTS[2]}'=='${current_location}' Reload Page | |
| 107 | + Go To ${homepage} | |
| 106 | 108 | Wait Until Page Contains Допороговые закупки Украины 10 |
| 107 | 109 | sleep 1 |
| 108 | 110 | Input Text id=search ${ARGUMENTS[1]} | ... | ... |
| ... | ... | @@ -10,7 +10,7 @@ ${telephone} +380976535447 |
| 10 | 10 | *** Keywords *** |
| 11 | 11 | Підготувати клієнт для користувача |
| 12 | 12 | [Arguments] @{ARGUMENTS} |
| 13 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 13 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 14 | 14 | ... ${ARGUMENTS[0]} == username |
| 15 | 15 | Open Browser ${USERS.users['${ARGUMENTS[0]}'].homepage} ${USERS.users['${username}'].browser} alias=${ARGUMENTS[0]} |
| 16 | 16 | Set Window Size @{USERS.users['${ARGUMENTS[0]}'].size} |
| ... | ... | @@ -39,7 +39,7 @@ ${telephone} +380976535447 |
| 39 | 39 | ${step_rate}= Get From Dictionary ${prepared_tender_data.data.minimalStep} amount |
| 40 | 40 | ${countryName}= Get From Dictionary ${prepared_tender_data.data.procuringEntity.address} countryName |
| 41 | 41 | ${delivery_end_date}= Get From Dictionary ${items[0].deliveryDate} endDate |
| 42 | - ${delivery_end_date}= convert_date_to_prom_format ${delivery_end_date} | |
| 42 | + ${delivery_end_date}= convert_datetime_to_dot_format ${delivery_end_date} | |
| 43 | 43 | ${cpv}= Convert To String "Картонки" |
| 44 | 44 | ${cpv_id}= Get From Dictionary ${items[0].classification} id |
| 45 | 45 | ${cpv_id_1}= Get Substring ${cpv_id} 0 3 | ... | ... |
| ... | ... | @@ -6,9 +6,11 @@ Library DateTime |
| 6 | 6 | *** Keywords *** |
| 7 | 7 | Підготувати клієнт для користувача |
| 8 | 8 | [Arguments] ${username} |
| 9 | - [Documentation] Відкрити брaвзер, створити обєкт api wrapper, тощо | |
| 10 | - ${url}= Get Broker Property By Username ${username} url | |
| 11 | - Open Browser ${url} ${USERS.users['${username}'].browser} alias=${username} | |
| 9 | + [Documentation] Відкрити браузер, створити об’єкт api wrapper, тощо | |
| 10 | + Open Browser | |
| 11 | + ... ${USERS.users['${username}'].homepage} | |
| 12 | + ... ${USERS.users['${username}'].browser} | |
| 13 | + ... alias=${username} | |
| 12 | 14 | Set Window Position @{USERS.users['${username}'].position} |
| 13 | 15 | Set Window Size @{USERS.users['${username}'].size} |
| 14 | 16 | Log Variables |
| ... | ... | @@ -21,9 +23,9 @@ Library DateTime |
| 21 | 23 | ... ${ARGUMENTS[2]} == id |
| 22 | 24 | Switch browser ${ARGUMENTS[0]} |
| 23 | 25 | ${current_location}= Get Location |
| 24 | - ${url}= Get Broker Property By Username ${ARGUMENTS[0]} url | |
| 25 | - Run Keyword If '${url}/#/tenderDetailes/${ARGUMENTS[2]}'=='${current_location}' Reload Page | |
| 26 | - Go To ${url} | |
| 26 | + ${homepage}= Set Variable ${USERS.users['${ARGUMENTS[0]}'].homepage} | |
| 27 | + Run Keyword If '${homepage}/#/tenderDetailes/${ARGUMENTS[2]}'=='${current_location}' Reload Page | |
| 28 | + Go To ${homepage} | |
| 27 | 29 | Wait Until Page Contains Офіційний майданчик державних закупівель України 10 |
| 28 | 30 | sleep 1 |
| 29 | 31 | Input Text id=j_idt18:datalist:j_idt67 ${ARGUMENTS[1]} | ... | ... |
| 1 | 1 | Default: |
| 2 | 2 | # These values are used by default unless a |
| 3 | 3 | # specific broker entry overrides them. |
| 4 | + intervals: | |
| 5 | + enquiry: 11 | |
| 6 | + tender: 18 | |
| 7 | + auction: 0 | |
| 8 | + qualification: 0 | |
| 9 | + award: 0 | |
| 10 | + complaint: 0 | |
| 4 | 11 | timeout_on_wait: 300 |
| 5 | - period_interval: 3 | |
| 6 | 12 | Quinta: |
| 13 | + intervals: | |
| 14 | + enquiry: 2 | |
| 15 | + tender: 5 | |
| 7 | 16 | keywords_file: openprocurement_client |
| 8 | - timeout_on_wait: 15 | |
| 9 | 17 | roles: |
| 10 | 18 | tender_owner: Tender_Owner |
| 11 | 19 | provider: Tender_User |
| 12 | 20 | provider1: Tender_User1 |
| 13 | 21 | viewer: Tender_Viewer |
| 22 | + timeout_on_wait: 15 | |
| 14 | 23 | E-tender: |
| 15 | 24 | keywords_file: etender |
| 16 | - url: http://bid.uat.e-tender.biz/ | |
| 17 | - timeout_on_wait: 60 | |
| 18 | 25 | roles: |
| 19 | 26 | tender_owner: E-tender_Owner |
| 20 | 27 | provider: E-tender_Provider1 |
| 21 | 28 | provider1: E-tender_Provider2 |
| 22 | 29 | viewer: E-tender_Viewer |
| 30 | + timeout_on_wait: 60 | |
| 23 | 31 | Netcast: |
| 24 | 32 | keywords_file: netcast |
| 25 | - url: http://dz2.byustudio.in.ua | |
| 26 | 33 | login: admin |
| 27 | 34 | password: uStudio |
| 28 | 35 | roles: |
| ... | ... | @@ -31,26 +38,24 @@ Netcast: |
| 31 | 38 | viewer: Netcast_Viewer |
| 32 | 39 | Newtend: |
| 33 | 40 | keywords_file: newtend |
| 34 | - url: http://openprocurement:test@dev23.newtend.com | |
| 35 | 41 | roles: |
| 36 | 42 | tender_owner: Newtend_Owner |
| 37 | 43 | provider: Newtend_Provider1 |
| 38 | 44 | viewer: Newtend_Viewer |
| 39 | 45 | Prom: |
| 46 | + intervals: | |
| 47 | + enquiry: 5 | |
| 48 | + tender: 31 | |
| 40 | 49 | keywords_file: prom |
| 41 | - url: http://dz.dz-test.net/ | |
| 42 | - period_interval: 31 | |
| 43 | 50 | roles: |
| 44 | 51 | tender_owner: Prom_Owner |
| 45 | 52 | viewer: Prom_Viewer |
| 46 | 53 | Publicbid: |
| 47 | 54 | keywords_file: publicbid |
| 48 | - url: https://public-bid.com.ua/ | |
| 49 | 55 | roles: |
| 50 | 56 | tender_owner: Publicbid_Owner |
| 51 | 57 | viewer: Publicbid_Viewer |
| 52 | 58 | SmartTender: |
| 53 | 59 | keywords_file: smarttender |
| 54 | - url: http://smarttender.biz/tenders | |
| 55 | 60 | roles: |
| 56 | 61 | viewer: SmartTender_Viewer | ... | ... |
| ... | ... | @@ -73,7 +73,7 @@ users: |
| 73 | 73 | Newtend_Owner: |
| 74 | 74 | broker: Newtend |
| 75 | 75 | username: Newtendtest |
| 76 | - homepage: "http://dev23.newtend.com/openprocurement/#/home/page/1" | |
| 76 | + homepage: "http://openprocurement:test@dev23.newtend.com/" | |
| 77 | 77 | login: openprocurement@mailinator.com |
| 78 | 78 | password: 123123 |
| 79 | 79 | browser: chrome |
| ... | ... | @@ -82,7 +82,7 @@ users: |
| 82 | 82 | Newtend_Provider1: |
| 83 | 83 | broker: Newtend |
| 84 | 84 | username: Newtendtest |
| 85 | - homepage: "http://dev23.newtend.com/openprocurement/tenders" | |
| 85 | + homepage: "http://openprocurement:test@dev23.newtend.com/" | |
| 86 | 86 | login: openprocboss@mailinator.com |
| 87 | 87 | password: 123123 |
| 88 | 88 | browser: chrome |
| ... | ... | @@ -91,7 +91,7 @@ users: |
| 91 | 91 | Newtend_Viewer: |
| 92 | 92 | broker: Newtend |
| 93 | 93 | username: Newtendtest |
| 94 | - homepage: "http://dev23.newtend.com/openprocurement/tenders" | |
| 94 | + homepage: "http://openprocurement:test@dev23.newtend.com/openprocurement/tenders" | |
| 95 | 95 | browser: chrome |
| 96 | 96 | position: [800, 400] |
| 97 | 97 | size: [800, 700] | ... | ... |
| 1 | -from datetime import date, datetime, timedelta | |
| 2 | -from dateutil.parser import parse | |
| 3 | -from dateutil.tz import tzlocal | |
| 4 | -from iso8601 import parse_date | |
| 5 | -from jsonpath_rw import parse as parse_path | |
| 6 | -from pytz import timezone | |
| 7 | -from robot.output import LOGGER | |
| 8 | -from robot.output.loggerhelper import Message | |
| 9 | -from robot.libraries.BuiltIn import BuiltIn | |
| 10 | -from robot.errors import HandlerExecutionFailed | |
| 11 | -from op_robot_tests.tests_files.initial_data import ( | |
| 12 | - test_tender_data | |
| 13 | -) | |
| 14 | -import time | |
| 15 | - | |
| 16 | -TIMEZONE = timezone('Europe/Kiev') | |
| 17 | - | |
| 18 | - | |
| 19 | -def convert_date_to_etender_format(isodate): | |
| 20 | - iso_dt = parse_date(isodate) | |
| 21 | - date_string = iso_dt.strftime("%d-%m-%Y") | |
| 22 | - return date_string | |
| 23 | - | |
| 24 | - | |
| 25 | -def convert_time_to_etender_format(isodate): | |
| 26 | - iso_dt = parse_date(isodate) | |
| 27 | - time_string = iso_dt.strftime("%H:%M") | |
| 28 | - return time_string |
| ... | ... | @@ -25,13 +25,13 @@ def create_fake_doc(): |
| 25 | 25 | return tf.name |
| 26 | 26 | |
| 27 | 27 | |
| 28 | -def test_tender_data(period_interval): | |
| 28 | +def test_tender_data(intervals): | |
| 29 | 29 | now = get_now() |
| 30 | 30 | return { |
| 31 | 31 | "title": u"[ТЕСТУВАННЯ] " + fake.catch_phrase(), |
| 32 | 32 | "mode": "test", |
| 33 | 33 | "submissionMethodDetails": "quick", |
| 34 | - "description": u"Тестовий тендер", # Error @prom when "Тестовый тендер" | |
| 34 | + "description": u"Тестовий тендер", | |
| 35 | 35 | "description_ru": u"Тестовый тендер", |
| 36 | 36 | "description_en": "Test tender", |
| 37 | 37 | "procuringEntity": { |
| ... | ... | @@ -58,11 +58,11 @@ def test_tender_data(period_interval): |
| 58 | 58 | } |
| 59 | 59 | }, |
| 60 | 60 | "value": { |
| 61 | - "amount": 50000, # Error @prom when float '50000.99' | |
| 61 | + "amount": 50000.99, | |
| 62 | 62 | "currency": u"UAH" |
| 63 | 63 | }, |
| 64 | 64 | "minimalStep": { |
| 65 | - "amount": 100, # Error @prom when float '100.1' | |
| 65 | + "amount": 100.1, | |
| 66 | 66 | "currency": u"UAH" |
| 67 | 67 | }, |
| 68 | 68 | "items": [ |
| ... | ... | @@ -72,8 +72,8 @@ def test_tender_data(period_interval): |
| 72 | 72 | "endDate": (now + timedelta(days=5)).isoformat() |
| 73 | 73 | }, |
| 74 | 74 | "deliveryLocation": { |
| 75 | - "latitude": u"49.8500° N", | |
| 76 | - "longitude": u"24.0167° E" | |
| 75 | + "latitude": 49.8500, | |
| 76 | + "longitude": 24.0167 | |
| 77 | 77 | }, |
| 78 | 78 | "deliveryAddress": { |
| 79 | 79 | "countryName": u"Україна", |
| ... | ... | @@ -109,149 +109,21 @@ def test_tender_data(period_interval): |
| 109 | 109 | ], |
| 110 | 110 | "enquiryPeriod": { |
| 111 | 111 | "startDate": (now).isoformat(), |
| 112 | - "endDate": (now + timedelta(minutes=1)).isoformat() | |
| 112 | + "endDate": (now + timedelta(minutes=( | |
| 113 | + intervals['enquiry']))).isoformat() | |
| 113 | 114 | }, |
| 114 | 115 | "tenderPeriod": { |
| 115 | 116 | "startDate": (now + timedelta(minutes=2)).isoformat(), |
| 116 | - "endDate": (now + timedelta(minutes=(2 + period_interval))).isoformat() | |
| 117 | + "endDate": (now + timedelta(minutes=( | |
| 118 | + intervals['tender']))).isoformat() | |
| 117 | 119 | } |
| 118 | 120 | } |
| 119 | 121 | |
| 120 | 122 | |
| 121 | -def prom_test_tender_data(): | |
| 123 | +def test_tender_data_multiple_lots(intervals): | |
| 122 | 124 | now = get_now() |
| 123 | - return { | |
| 124 | - "title": fake.catch_phrase(), | |
| 125 | - "mode": "test", | |
| 126 | - "submissionMethodDetails": "quick", | |
| 127 | - "description": u"Тестовий тендер", # Error @prom when "Тестовый тендер" | |
| 128 | - "description_ru": u"Тестовый тендер", | |
| 129 | - "description_en": "Test tender", | |
| 130 | - "procuringEntity": { | |
| 131 | - "name": fake.company(), | |
| 132 | - "name_ru": fake_ru.company(), | |
| 133 | - "name_en": fake_en.company(), | |
| 134 | - "identifier": { | |
| 135 | - "scheme": u"UA-EDR", | |
| 136 | - "id": u"0000{}".format(fake.pyint()), | |
| 137 | - "uri": fake.image_url(width=None, height=None) | |
| 138 | - }, | |
| 139 | - "address": { | |
| 140 | - "countryName": u"Україна", | |
| 141 | - "countryName_ru": u"Украина", | |
| 142 | - "countryName_en": "Ukraine", | |
| 143 | - "postalCode": fake.postalcode(), | |
| 144 | - "region": u"м. Київ", | |
| 145 | - "locality": u"м. Київ", | |
| 146 | - "streetAddress": fake.street_address() | |
| 147 | - }, | |
| 148 | - "contactPoint": { | |
| 149 | - "name": fake.name(), | |
| 150 | - "telephone": fake.phone_number() | |
| 151 | - } | |
| 152 | - }, | |
| 153 | - "value": { | |
| 154 | - "amount": 50000, # Error @prom when float '50000.99' | |
| 155 | - "currency": u"UAH" | |
| 156 | - }, | |
| 157 | - "minimalStep": { | |
| 158 | - "amount": 100, # Error @prom when float '100.1' | |
| 159 | - "currency": u"UAH" | |
| 160 | - }, | |
| 161 | - "items": [ | |
| 162 | - { | |
| 163 | - "description": fake.catch_phrase(), | |
| 164 | - "deliveryDate": { | |
| 165 | - "startDate": (now + timedelta(days=4)).isoformat(), | |
| 166 | - "endDate": (now + timedelta(days=5)).isoformat() | |
| 167 | - }, | |
| 168 | - "deliveryLocation": { | |
| 169 | - "latitude": "49.8500° N", | |
| 170 | - "longitude": "24.0167° E" | |
| 171 | - }, | |
| 172 | - "deliveryAddress": { | |
| 173 | - "countryName": u"Україна", | |
| 174 | - "countryName_ru": u"Украина", | |
| 175 | - "countryName_en": "Ukraine", | |
| 176 | - "postalCode": fake.postalcode(), | |
| 177 | - "region": u"м. Київ", | |
| 178 | - "locality": u"м. Київ", | |
| 179 | - "streetAddress": fake.street_address() | |
| 180 | - }, | |
| 181 | - "classification": { | |
| 182 | - "scheme": u"CPV", | |
| 183 | - "id": u"44617100-9", | |
| 184 | - "description": u"Картонки", | |
| 185 | - "description_ru": u"Большие картонные коробки", | |
| 186 | - "description_en": u"Cartons" | |
| 187 | - }, | |
| 188 | - "additionalClassifications": [ | |
| 189 | - { | |
| 190 | - "scheme": u"ДКПП", | |
| 191 | - "id": u"17.21.1", | |
| 192 | - "description": u"Папір і картон гофровані, паперова й картонна тара" | |
| 193 | - } | |
| 194 | - ], | |
| 195 | - "unit": { | |
| 196 | - "name": u"кілограм", | |
| 197 | - "name_ru": u"килограмм", | |
| 198 | - "name_en": "kilogram", | |
| 199 | - "code": u"KGM" | |
| 200 | - }, | |
| 201 | - "quantity": fake.pyint() | |
| 202 | - } | |
| 203 | - ], | |
| 204 | - "enquiryPeriod": { | |
| 205 | - "startDate": (now + timedelta(days=1)).isoformat(), | |
| 206 | - "endDate": (now + timedelta(days=2)).isoformat() | |
| 207 | - }, | |
| 208 | - "tenderPeriod": { | |
| 209 | - "startDate": (now + timedelta(days=3)).isoformat(), | |
| 210 | - "endDate": (now + timedelta(days=5)).isoformat() | |
| 211 | - } | |
| 212 | - } | |
| 213 | - | |
| 214 | - | |
| 215 | -def test_tender_data_multiple_lots(period_interval): | |
| 216 | - now = get_now() | |
| 217 | - return { | |
| 218 | - "title": fake.catch_phrase(), | |
| 219 | - "mode": "test", | |
| 220 | - "submissionMethodDetails": "quick", | |
| 221 | - "description": u"Тестовий тендер", | |
| 222 | - "description_ru": u"Тестовый тендер", | |
| 223 | - "description_en": "Test tender", | |
| 224 | - "procuringEntity": { | |
| 225 | - "name": fake.company(), | |
| 226 | - "name_ru": fake_ru.company(), | |
| 227 | - "name_en": fake_en.company(), | |
| 228 | - "identifier": { | |
| 229 | - "scheme": u"UA-EDR", | |
| 230 | - "id": u"0000{}".format(fake.pyint()), | |
| 231 | - "uri": fake.image_url(width=None, height=None) | |
| 232 | - }, | |
| 233 | - "address": { | |
| 234 | - "countryName": u"Україна", | |
| 235 | - "countryName_ru": u"Украина", | |
| 236 | - "countryName_en": "Ukraine", | |
| 237 | - "postalCode": fake.postalcode(), | |
| 238 | - "region": u"м. Київ", | |
| 239 | - "locality": u"м. Київ", | |
| 240 | - "streetAddress": fake.street_address() | |
| 241 | - }, | |
| 242 | - "contactPoint": { | |
| 243 | - "name": fake.name(), | |
| 244 | - "telephone": fake.phone_number() | |
| 245 | - } | |
| 246 | - }, | |
| 247 | - "value": { | |
| 248 | - "amount": 50000.99, | |
| 249 | - "currency": u"UAH" | |
| 250 | - }, | |
| 251 | - "minimalStep": { | |
| 252 | - "amount": 100.1, | |
| 253 | - "currency": u"UAH" | |
| 254 | - }, | |
| 125 | + t_data = test_tender_data(intervals) | |
| 126 | + t_data.update({ | |
| 255 | 127 | "items": [ |
| 256 | 128 | { |
| 257 | 129 | "description": fake.catch_phrase(), |
| ... | ... | @@ -413,16 +285,9 @@ def test_tender_data_multiple_lots(period_interval): |
| 413 | 285 | }, |
| 414 | 286 | "quantity": fake.pyint() |
| 415 | 287 | } |
| 416 | - ], | |
| 417 | - "enquiryPeriod": { | |
| 418 | - "startDate": (now).isoformat(), | |
| 419 | - "endDate": (now + timedelta(minutes=1)).isoformat() | |
| 420 | - }, | |
| 421 | - "tenderPeriod": { | |
| 422 | - "startDate": (now + timedelta(minutes=2)).isoformat(), | |
| 423 | - "endDate": (now + timedelta(minutes=(2 + period_interval))).isoformat() | |
| 424 | - } | |
| 425 | - } | |
| 288 | + ] | |
| 289 | + }) | |
| 290 | + return t_data | |
| 426 | 291 | |
| 427 | 292 | |
| 428 | 293 | def test_question_data(): |
| ... | ... | @@ -539,7 +404,7 @@ def auction_bid(): |
| 539 | 404 | "value": { |
| 540 | 405 | "amount": 200, |
| 541 | 406 | "currency": "UAH", |
| 542 | - "valueAddedTaxIncluded": true | |
| 407 | + "valueAddedTaxIncluded": "true" | |
| 543 | 408 | } |
| 544 | 409 | } |
| 545 | 410 | }) | ... | ... |
| ... | ... | @@ -7,12 +7,10 @@ Library Selenium2Library |
| 7 | 7 | Library DateTime |
| 8 | 8 | Library Selenium2Screenshots |
| 9 | 9 | Library DebugLibrary |
| 10 | -Library op_robot_tests.tests_files.brokers.openprocurement_client_helper | |
| 11 | 10 | |
| 12 | 11 | *** Keywords *** |
| 13 | 12 | TestSuiteSetup |
| 14 | 13 | Завантажуємо дані про користувачів і майданчики |
| 15 | - Підготовка початкових даних | |
| 16 | 14 | |
| 17 | 15 | Set Suite Variable With Default Value |
| 18 | 16 | [Arguments] ${suite_var} ${def_value} |
| ... | ... | @@ -51,9 +49,9 @@ Set Suite Variable With Default Value |
| 51 | 49 | Get Broker Property |
| 52 | 50 | [Arguments] ${broker_name} ${property} |
| 53 | 51 | [Documentation] |
| 54 | - ... This keyword returns a property of specified broker | |
| 55 | - ... if that property exists, otherwise, it returns a | |
| 56 | - ... default value. | |
| 52 | + ... This keyword returns a property of specified broker | |
| 53 | + ... if that property exists, otherwise, it returns a | |
| 54 | + ... default value. | |
| 57 | 55 | ${status}= Run Keyword And Return Status Should Contain ${BROKERS['${broker_name}']} ${property} |
| 58 | 56 | Return From Keyword If ${status} ${BROKERS['${broker_name}'].${property}} |
| 59 | 57 | # If broker doesn't have that property, fall back to default value |
| ... | ... | @@ -62,37 +60,39 @@ Get Broker Property |
| 62 | 60 | |
| 63 | 61 | Get Broker Property By Username |
| 64 | 62 | [Documentation] |
| 65 | - ... This keyword gets the corresponding broker name | |
| 66 | - ... for a specified username and then calls | |
| 67 | - ... "Get Broker Property" | |
| 63 | + ... This keyword gets the corresponding broker name | |
| 64 | + ... for a specified username and then calls | |
| 65 | + ... "Get Broker Property" | |
| 68 | 66 | [Arguments] ${username} ${property} |
| 69 | 67 | ${broker_name}= Get Variable Value ${USERS.users['${username}'].broker} |
| 70 | 68 | Run Keyword And Return Get Broker Property ${broker_name} ${property} |
| 71 | 69 | |
| 72 | 70 | Підготовка початкових даних |
| 73 | - @{QUESTIONS} = Create list | |
| 71 | + @{QUESTIONS}= Create list | |
| 74 | 72 | ${question}= test question data |
| 75 | - Append to list ${QUESTIONS} ${question} | |
| 76 | - Set Global Variable ${QUESTIONS} | |
| 77 | - @{ANSWERS} = Create list | |
| 73 | + Append to list ${QUESTIONS} ${question} | |
| 74 | + Set Global Variable @{QUESTIONS} | |
| 75 | + @{ANSWERS}= Create list | |
| 78 | 76 | ${answer}= test_question_answer_data |
| 79 | - Append to list ${ANSWERS} ${answer} | |
| 80 | - Set Global Variable ${ANSWERS} | |
| 81 | - @{COMPLAINTS} = Create list | |
| 77 | + Append to list ${ANSWERS} ${answer} | |
| 78 | + Set Global Variable @{ANSWERS} | |
| 79 | + @{COMPLAINTS}= Create list | |
| 82 | 80 | ${complaint}= test_complaint_data |
| 83 | - Append to list ${COMPLAINTS} ${complaint} | |
| 84 | - Set Global Variable ${COMPLAINTS} | |
| 85 | - @{REPLIES} = Create list | |
| 81 | + Append to list ${COMPLAINTS} ${complaint} | |
| 82 | + Set Global Variable @{COMPLAINTS} | |
| 83 | + @{REPLIES}= Create list | |
| 86 | 84 | ${reply}= test_complaint_reply_data |
| 87 | - Append to list ${REPLIES} ${reply} | |
| 88 | - Set Global Variable ${REPLIES} | |
| 89 | - ${period_interval}= Get Broker Property By Username ${tender_owner} period_interval | |
| 90 | - ${INITIAL_TENDER_DATA}= prepare_test_tender_data ${period_interval} ${mode} | |
| 91 | - Set Global Variable ${INITIAL_TENDER_DATA} | |
| 85 | + Append to list ${REPLIES} ${reply} | |
| 86 | + Set Global Variable @{REPLIES} | |
| 87 | + ${custom_intervals}= Get Broker Property By Username ${tender_owner} intervals | |
| 88 | + ${default_intervals}= Get Broker Property Default intervals | |
| 89 | + ${period_intervals}= merge_dicts ${default_intervals} ${custom_intervals} | |
| 90 | + ${tender_data}= prepare_test_tender_data ${period_intervals} ${mode} | |
| 92 | 91 | ${TENDER}= Create Dictionary |
| 93 | 92 | Set Global Variable ${TENDER} |
| 94 | 93 | Log ${TENDER} |
| 95 | - Log ${INITIAL_TENDER_DATA} | |
| 94 | + Log ${tender_data} | |
| 95 | + [return] ${tender_data} | |
| 96 | 96 | |
| 97 | 97 | Завантажуємо бібліотеку з реалізацією для майданчика ${keywords_file} |
| 98 | 98 | Import Resource ${CURDIR}/brokers/${keywords_file}.robot |
| ... | ... | @@ -101,8 +101,8 @@ Get Broker Property By Username |
| 101 | 101 | Дочекатись синхронізації з майданчиком |
| 102 | 102 | [Arguments] ${username} |
| 103 | 103 | [Documentation] |
| 104 | - ... Get ${wait_timeout} for specified user and wait | |
| 105 | - ... until that timeout runs out. | |
| 104 | + ... Get ${wait_timeout} for specified user and wait | |
| 105 | + ... until that timeout runs out. | |
| 106 | 106 | ${now}= Get Current Date |
| 107 | 107 | ${delta}= Subtract Date From Date ${now} ${TENDER['LAST_MODIFICATION_DATE']} |
| 108 | 108 | ${timeout_on_wait}= Get Broker Property By Username ${username} timeout_on_wait |
| ... | ... | @@ -110,51 +110,43 @@ Get Broker Property By Username |
| 110 | 110 | Run Keyword If ${wait_timeout}>0 Sleep ${wait_timeout} |
| 111 | 111 | |
| 112 | 112 | Звірити поле тендера |
| 113 | - [Arguments] ${username} ${field} | |
| 114 | - ${field_value}= Get_From_Object ${INITIAL_TENDER_DATA.data} ${field} | |
| 115 | - Звірити поле ${username} ${field} ${field_value} | |
| 116 | - | |
| 117 | -Звірити поле | |
| 118 | - [Arguments] ${username} ${field} ${subject} | |
| 119 | - ${field_response}= Викликати для учасника ${username} Отримати інформацію із тендера ${field} | |
| 120 | - Should Not Be Equal ${field_response} ${None} | |
| 121 | - Should Be Equal ${subject} ${field_response} Майданчик ${USERS.users['${username}'].broker} | |
| 122 | - | |
| 123 | -Звірити поле створеного тендера | |
| 124 | - [Arguments] ${initial} ${tender_data} ${field} | |
| 125 | - ${field_value}= Get_From_Object ${initial} ${field} | |
| 126 | - ${field_response}= Get_From_Object ${tender_data} ${field} | |
| 127 | - Should Not Be Equal ${field_response} ${None} | |
| 128 | - Should Not Be Equal ${field_value} ${None} | |
| 129 | - Should Be Equal ${field_value} ${field_response} | |
| 113 | + [Arguments] ${username} ${tender_data} ${field} | |
| 114 | + ${left}= Get_From_Object ${tender_data.data} ${field} | |
| 115 | + ${right}= Викликати для учасника ${username} Отримати інформацію із тендера ${field} | |
| 116 | + Порівняти об'єкти ${left} ${right} | |
| 117 | + | |
| 118 | +Порівняти об'єкти | |
| 119 | + [Arguments] ${left} ${right} | |
| 120 | + Should Not Be Equal ${left} ${None} | |
| 121 | + Should Not Be Equal ${right} ${None} | |
| 122 | + Should Be Equal ${left} ${right} | |
| 130 | 123 | |
| 131 | 124 | Звірити дату тендера |
| 132 | - [Arguments] ${username} ${field} | |
| 133 | - ${isodate}= Get_From_Object ${INITIAL_TENDER_DATA.data} ${field} | |
| 134 | - Should Not Be Equal ${isodate} ${None} | |
| 135 | - Звірити дату ${username} ${field} ${isodate} | |
| 125 | + [Arguments] ${username} ${tender_data} ${field} | |
| 126 | + ${left}= Get_From_Object ${tender_data.data} ${field} | |
| 127 | + ${right}= Викликати для учасника ${username} Отримати інформацію із тендера ${field} | |
| 128 | + Звірити дату ${left} ${right} | |
| 136 | 129 | |
| 137 | 130 | Звірити дату |
| 138 | - [Arguments] ${username} ${field} ${subject} | |
| 139 | - ${field_date}= Викликати для учасника ${username} Отримати інформацію із тендера ${field} | |
| 140 | - ${returned}= compare_date ${subject} ${field_date} | |
| 141 | - Should Not Be Equal ${field_date} ${None} | |
| 142 | - Should Not Be Equal ${returned} ${None} | |
| 143 | - Should Be True '${returned}' == 'True' | |
| 131 | + [Arguments] ${left} ${right} | |
| 132 | + Should Not Be Equal ${left} ${None} | |
| 133 | + Should Not Be Equal ${right} ${None} | |
| 134 | + ${status}= compare_date ${left} ${right} | |
| 135 | + Should Be True ${status} | |
| 144 | 136 | |
| 145 | 137 | Звірити поля предметів закупівлі багатопредметного тендера |
| 146 | - [Arguments] ${username} ${field} | |
| 138 | + [Arguments] ${username} ${tender_data} ${field} | |
| 147 | 139 | Дочекатись синхронізації з майданчиком ${username} |
| 148 | - @{items}= Get_From_Object ${INITIAL_TENDER_DATA.data} items | |
| 140 | + @{items}= Get_From_Object ${tender_data.data} items | |
| 149 | 141 | ${len_of_items}= Get Length ${items} |
| 150 | 142 | :FOR ${index} IN RANGE ${len_of_items} |
| 151 | 143 | \ Log ${index} |
| 152 | 144 | \ Звірити поле тендера ${viewer} items[${index}].${field} |
| 153 | 145 | |
| 154 | 146 | Звірити дату предметів закупівлі багатопредметного тендера |
| 155 | - [Arguments] ${username} ${field} | |
| 147 | + [Arguments] ${username} ${tender_data} ${field} | |
| 156 | 148 | Дочекатись синхронізації з майданчиком ${username} |
| 157 | - @{items}= Get_From_Object ${INITIAL_TENDER_DATA.data} items | |
| 149 | + @{items}= Get_From_Object ${tender_data.data} items | |
| 158 | 150 | ${len_of_items}= Get Length ${items} |
| 159 | 151 | :FOR ${index} IN RANGE ${len_of_items} |
| 160 | 152 | \ Log ${index} |
| ... | ... | @@ -162,13 +154,13 @@ Get Broker Property By Username |
| 162 | 154 | |
| 163 | 155 | Викликати для учасника |
| 164 | 156 | [Documentation] |
| 165 | - ... Cause sometimes keyword SHOULD fail to pass the testcase, | |
| 166 | - ... this keyword takes "shouldfail" argument as first one in @{arguments} | |
| 167 | - ... and switches the behaviour of keyword and "shouldfail" | |
| 157 | + ... Cause sometimes keyword SHOULD fail to pass the testcase, | |
| 158 | + ... this keyword takes "shouldfail" argument as first one in @{arguments} | |
| 159 | + ... and switches the behaviour of keyword and "shouldfail" | |
| 168 | 160 | [Arguments] ${username} ${command} @{arguments} |
| 169 | 161 | Log ${username} |
| 170 | 162 | Log ${command} |
| 171 | - Log ${arguments} | |
| 163 | + Log Many @{arguments} | |
| 172 | 164 | ${state}= change_state ${arguments} |
| 173 | 165 | Run Keyword And Return If '${state}' == 'shouldfail' SwitchState ${username} ${command} @{arguments} |
| 174 | 166 | Run Keyword And Return If '${state}' == 'pass' Normal ${username} ${command} @{arguments} |
| ... | ... | @@ -177,17 +169,17 @@ Normal |
| 177 | 169 | [Arguments] ${username} ${command} @{arguments} |
| 178 | 170 | Log ${username} |
| 179 | 171 | Log ${command} |
| 180 | - Log ${arguments} | |
| 172 | + Log Many @{arguments} | |
| 181 | 173 | ${keywords_file}= Get Broker Property By Username ${username} keywords_file |
| 182 | 174 | Run Keyword And Return ${keywords_file}.${command} ${username} @{arguments} |
| 183 | 175 | |
| 184 | 176 | SwitchState |
| 185 | 177 | [Arguments] ${username} ${command} @{arguments} |
| 186 | - log ${username} | |
| 187 | - log ${command} | |
| 188 | - log ${arguments} | |
| 178 | + Log ${username} | |
| 179 | + Log ${command} | |
| 180 | + Log Many @{arguments} | |
| 189 | 181 | Remove From List ${arguments} 0 |
| 190 | - log ${arguments} | |
| 182 | + Log Many @{arguments} | |
| 191 | 183 | ${keywords_file}= Get Broker Property By Username ${username} keywords_file |
| 192 | 184 | ${status} ${value}= run_keyword_and_ignore_keyword_definitions ${keywords_file}.${command} ${username} @{arguments} |
| 193 | 185 | Run keyword if '${status}' == 'PASS' Log Учасник ${username} зміг виконати "${command}" WARN |
| ... | ... | @@ -199,13 +191,13 @@ SwitchState |
| 199 | 191 | Run Keyword If ${wait_timeout}>0 Sleep ${wait_timeout} |
| 200 | 192 | |
| 201 | 193 | Дочекатись дати початку прийому пропозицій |
| 202 | - Дочекатись дати ${TENDER_DATA.data.tenderPeriod.startDate} | |
| 194 | + Дочекатись дати ${tender_data.data.tenderPeriod.startDate} | |
| 203 | 195 | |
| 204 | 196 | Дочекатись дати закінчення прийому пропозицій |
| 205 | - Дочекатись дати ${TENDER_DATA.data.tenderPeriod.endDate} | |
| 197 | + Дочекатись дати ${tender_data.data.tenderPeriod.endDate} | |
| 206 | 198 | |
| 207 | 199 | Дочекатись дати початку аукціону |
| 208 | - Дочекатись дати ${TENDER_DATA.data.auctionPeriod.startDate} | |
| 200 | + Дочекатись дати ${tender_data.data.auctionPeriod.startDate} | |
| 209 | 201 | |
| 210 | 202 | Дочекатись дати закінчення аукціону |
| 211 | - Дочекатись дати ${TENDER_DATA.data.auctionPeriod.endDate} | |
| 203 | + Дочекатись дати ${tender_data.data.auctionPeriod.endDate} | ... | ... |
| ... | ... | @@ -18,7 +18,8 @@ ${broker} Quinta |
| 18 | 18 | *** Test Cases *** |
| 19 | 19 | Можливість оголосити багатопредметний тендер |
| 20 | 20 | [Tags] ${USERS.users['${tender_owner}'].broker}: Можливість оголосити тендер |
| 21 | - ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${INITIAL_TENDER_DATA} | |
| 21 | + ${tender_data}= Підготовка початкових даних | |
| 22 | + ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${tender_data} | |
| 22 | 23 | ${LAST_MODIFICATION_DATE}= Get Current Date |
| 23 | 24 | Set To Dictionary ${TENDER} TENDER_UAID ${TENDER_UAID} |
| 24 | 25 | Set To Dictionary ${TENDER} LAST_MODIFICATION_DATE ${LAST_MODIFICATION_DATE} | ... | ... |
| 1 | 1 | # -*- coding: utf-8 - |
| 2 | -import os | |
| 3 | -from munch import munchify, Munch, fromYAML | |
| 4 | -from json import load | |
| 5 | -from iso8601 import parse_date | |
| 6 | -from robot.output import LOGGER | |
| 7 | -from robot.output.loggerhelper import Message | |
| 8 | -from robot.libraries.BuiltIn import BuiltIn | |
| 9 | -from robot.errors import HandlerExecutionFailed | |
| 10 | -from datetime import datetime, timedelta, date | |
| 2 | +from datetime import datetime, timedelta | |
| 11 | 3 | from dateutil.parser import parse |
| 12 | -from dateutil.tz import tzlocal | |
| 13 | -from pytz import timezone | |
| 14 | 4 | from dpath.util import set as xpathset |
| 5 | +from iso8601 import parse_date | |
| 6 | +from json import load | |
| 15 | 7 | from jsonpath_rw import parse as parse_path |
| 16 | -import time | |
| 8 | +from munch import fromYAML, Munch, munchify | |
| 9 | +from pytz import timezone | |
| 10 | +from robot.errors import HandlerExecutionFailed | |
| 11 | +from robot.libraries.BuiltIn import BuiltIn | |
| 12 | +from robot.output import LOGGER | |
| 13 | +from robot.output.loggerhelper import Message | |
| 14 | +# These imports are not pointless. Robot's resource and testsuite files | |
| 15 | +# can access them by simply importing library "service_keywords". | |
| 16 | +# Please ignore the warning given by Flake8 or other linter. | |
| 17 | 17 | from .initial_data import ( |
| 18 | - test_tender_data, test_question_data, test_question_answer_data, | |
| 19 | - test_bid_data, test_award_data, test_complaint_data, test_complaint_reply_data, test_tender_data_multiple_lots, | |
| 20 | - auction_bid, prom_test_tender_data, create_fake_doc | |
| 18 | + auction_bid, create_fake_doc, | |
| 19 | + test_award_data, test_bid_data, test_complaint_data, | |
| 20 | + test_complaint_reply_data, test_question_answer_data, | |
| 21 | + test_question_data, test_tender_data, test_tender_data_multiple_lots | |
| 21 | 22 | ) |
| 22 | -import calendar | |
| 23 | +import os | |
| 23 | 24 | |
| 24 | 25 | |
| 25 | 26 | TZ = timezone(os.environ['TZ'] if 'TZ' in os.environ else 'Europe/Kiev') |
| 26 | 27 | |
| 28 | + | |
| 27 | 29 | def get_now(): |
| 28 | 30 | return datetime.now(TZ) |
| 29 | 31 | |
| 32 | + | |
| 30 | 33 | def get_date(): |
| 31 | - return get_now().isoformat() | |
| 34 | + return get_now().isoformat() | |
| 35 | + | |
| 32 | 36 | |
| 33 | 37 | def get_file_contents(path): |
| 34 | 38 | with open(path, 'r') as f: |
| 35 | 39 | return unicode(f.read()) or u'' |
| 36 | 40 | |
| 41 | + | |
| 37 | 42 | def change_state(arguments): |
| 38 | 43 | try: |
| 39 | 44 | if arguments[0] == "shouldfail": |
| ... | ... | @@ -42,22 +47,26 @@ def change_state(arguments): |
| 42 | 47 | except IndexError: |
| 43 | 48 | return "pass" |
| 44 | 49 | |
| 45 | -def prepare_prom_test_tender_data(): | |
| 46 | - return munchify({'data': prom_test_tender_data()}) | |
| 50 | + | |
| 51 | +def prepare_prom_test_tender_data(period_intervals, mode): | |
| 52 | + t_data = prepare_test_tender_data(period_intervals, mode) | |
| 53 | + return munchify({'data': t_data}) | |
| 54 | + | |
| 47 | 55 | |
| 48 | 56 | def compare_date(data1, data2): |
| 49 | - data1=parse(data1) | |
| 50 | - data2=parse(data2) | |
| 57 | + data1 = parse(data1) | |
| 58 | + data2 = parse(data2) | |
| 51 | 59 | if data1.tzinfo is None: |
| 52 | 60 | data1 = TZ.localize(data1) |
| 53 | 61 | if data2.tzinfo is None: |
| 54 | 62 | data2 = TZ.localize(data2) |
| 55 | 63 | |
| 56 | - delta = (data1-data2).total_seconds() | |
| 64 | + delta = (data1 - data2).total_seconds() | |
| 57 | 65 | if abs(delta) > 60: |
| 58 | - return False | |
| 66 | + return False | |
| 59 | 67 | return True |
| 60 | 68 | |
| 69 | + | |
| 61 | 70 | def log_object_data(data, file_name=None, format="yaml"): |
| 62 | 71 | """Log object data in pretty format (JSON or YAML) |
| 63 | 72 | |
| ... | ... | @@ -89,10 +98,6 @@ def log_object_data(data, file_name=None, format="yaml"): |
| 89 | 98 | with open(os.path.join(output_dir, file_name + '.' + format), "w") as file_obj: |
| 90 | 99 | file_obj.write(data) |
| 91 | 100 | |
| 92 | -def convert_date_to_prom_format(isodate): | |
| 93 | - iso_dt=parse_date(isodate) | |
| 94 | - day_string = iso_dt.strftime("%d.%m.%Y %H:%M") | |
| 95 | - return day_string | |
| 96 | 101 | |
| 97 | 102 | def load_initial_data_from(file_name): |
| 98 | 103 | if not os.path.exists(file_name): |
| ... | ... | @@ -104,12 +109,12 @@ def load_initial_data_from(file_name): |
| 104 | 109 | return fromYAML(file_obj) |
| 105 | 110 | |
| 106 | 111 | |
| 107 | -def prepare_test_tender_data(period_interval=2, mode='single'): | |
| 112 | +def prepare_test_tender_data(period_intervals, mode): | |
| 108 | 113 | if mode == 'single': |
| 109 | - return munchify({'data': test_tender_data(period_interval=period_interval)}) | |
| 114 | + return munchify({'data': test_tender_data(period_intervals)}) | |
| 110 | 115 | elif mode == 'multi': |
| 111 | - return munchify({'data': test_tender_data_multiple_lots(period_interval=period_interval)}) | |
| 112 | - raise ValueError('A very specific bad thing happened') | |
| 116 | + return munchify({'data': test_tender_data_multiple_lots(period_intervals)}) | |
| 117 | + raise ValueError('Invalid mode for test_tender_data') | |
| 113 | 118 | |
| 114 | 119 | |
| 115 | 120 | def run_keyword_and_ignore_keyword_definitions(name, *args): |
| ... | ... | @@ -130,7 +135,7 @@ def run_keyword_and_ignore_keyword_definitions(name, *args): |
| 130 | 135 | """ |
| 131 | 136 | try: |
| 132 | 137 | status, _ = BuiltIn().run_keyword_and_ignore_error(name, *args) |
| 133 | - except HandlerExecutionFailed, e: | |
| 138 | + except HandlerExecutionFailed: | |
| 134 | 139 | LOGGER.log_message(Message("Keyword {} not implemented", "ERROR")) |
| 135 | 140 | return "FAIL", "" |
| 136 | 141 | return status, _ |
| ... | ... | @@ -174,62 +179,35 @@ def wait_to_date(date_stamp): |
| 174 | 179 | return 0 |
| 175 | 180 | return wait_seconds |
| 176 | 181 | |
| 177 | -##GUI Frontends common | |
| 182 | + | |
| 183 | +def merge_dicts(left, right): | |
| 184 | + new = {} | |
| 185 | + new.update(left) | |
| 186 | + new.update(right) | |
| 187 | + return new | |
| 188 | + | |
| 189 | + | |
| 190 | +# GUI Frontends common | |
| 191 | +def add_data_for_gui_frontends(tender_data): | |
| 192 | + now = datetime.now() | |
| 193 | + # tender_data.data.enquiryPeriod['startDate'] = (now + timedelta(minutes=2)).isoformat() | |
| 194 | + tender_data.data.enquiryPeriod['endDate'] = (now + timedelta(minutes=6)).isoformat() | |
| 195 | + tender_data.data.tenderPeriod['startDate'] = (now + timedelta(minutes=7)).isoformat() | |
| 196 | + tender_data.data.tenderPeriod['endDate'] = (now + timedelta(minutes=11)).isoformat() | |
| 197 | + return tender_data | |
| 198 | + | |
| 199 | + | |
| 178 | 200 | def convert_date_to_slash_format(isodate): |
| 179 | - iso_dt=parse_date(isodate) | |
| 201 | + iso_dt = parse_date(isodate) | |
| 180 | 202 | date_string = iso_dt.strftime("%d/%m/%Y") |
| 181 | - return date_string | |
| 203 | + return date_string | |
| 204 | + | |
| 205 | + | |
| 206 | +def convert_datetime_to_dot_format(isodate): | |
| 207 | + iso_dt = parse_date(isodate) | |
| 208 | + day_string = iso_dt.strftime("%d.%m.%Y %H:%M") | |
| 209 | + return day_string | |
| 182 | 210 | |
| 183 | -def Add_data_for_GUI_FrontEnds(INITIAL_TENDER_DATA): | |
| 184 | - now = datetime.now() | |
| 185 | - #INITIAL_TENDER_DATA.data.enquiryPeriod['startDate'] = (now + timedelta(minutes=2)).isoformat() | |
| 186 | - INITIAL_TENDER_DATA.data.enquiryPeriod['endDate'] = (now + timedelta(minutes=6)).isoformat() | |
| 187 | - INITIAL_TENDER_DATA.data.tenderPeriod['startDate'] = (now + timedelta(minutes=7)).isoformat() | |
| 188 | - INITIAL_TENDER_DATA.data.tenderPeriod['endDate'] = (now + timedelta(minutes=11)).isoformat() | |
| 189 | - return INITIAL_TENDER_DATA | |
| 190 | 211 | |
| 191 | 212 | def local_path_to_file(file_name): |
| 192 | 213 | return os.path.join(os.path.dirname(__file__), 'documents', file_name) |
| 193 | - | |
| 194 | -## E-Tender | |
| 195 | -def convert_date_to_etender_format(isodate): | |
| 196 | - iso_dt=parse_date(isodate) | |
| 197 | - date_string = iso_dt.strftime("%d-%m-%Y") | |
| 198 | - return date_string | |
| 199 | - | |
| 200 | -def convert_date_for_delivery(isodate): | |
| 201 | - iso_dt=parse_date(isodate) | |
| 202 | - date_string = iso_dt.strftime("%Y-%m-%d %H:%M") | |
| 203 | - return date_string | |
| 204 | - | |
| 205 | -def convert_time_to_etender_format(isodate): | |
| 206 | - iso_dt=parse_date(isodate) | |
| 207 | - time_string = iso_dt.strftime("%H:%M") | |
| 208 | - return time_string | |
| 209 | - | |
| 210 | -def procuringEntity_name(INITIAL_TENDER_DATA): | |
| 211 | - INITIAL_TENDER_DATA.data.procuringEntity['name'] = u"Повна назва невідомо чого" | |
| 212 | - return INITIAL_TENDER_DATA | |
| 213 | - | |
| 214 | -##Newtend | |
| 215 | -def newtend_date_picker_index(isodate): | |
| 216 | - now = datetime.today() | |
| 217 | - date_str = '01' + str(now.month) + str(now.year) | |
| 218 | - first_day_of_month = datetime.strptime(date_str, "%d%m%Y") | |
| 219 | - mod = first_day_of_month.isoweekday() - 2 | |
| 220 | - iso_dt=parse_date(isodate) | |
| 221 | - last_day_of_month = calendar.monthrange(now.year, now.month)[1] | |
| 222 | - #LOGGER.log_message(Message("last_day_of_month: {}".format(last_day_of_month), "INFO")) | |
| 223 | - if now.day>iso_dt.day: | |
| 224 | - mod = calendar.monthrange(now.year, now.month)[1] + mod | |
| 225 | - return mod + iso_dt.day | |
| 226 | - | |
| 227 | -def Update_data_for_Newtend(INITIAL_TENDER_DATA): | |
| 228 | - #INITIAL_TENDER_DATA.data.items[0].classification['description'] = u"Картонки" | |
| 229 | - INITIAL_TENDER_DATA.data.procuringEntity['name'] = u"openprocurement" | |
| 230 | - return INITIAL_TENDER_DATA | |
| 231 | - | |
| 232 | -def subtract_from_time(date_time,substr_min,substr_sec): | |
| 233 | - now = datetime.strptime(date_time,"%d.%m.%Y %H:%M") | |
| 234 | - now = (now - timedelta(minutes=int(substr_min), seconds = int (substr_sec) )).isoformat() | |
| 235 | - return now | ... | ... |
| ... | ... | @@ -21,7 +21,8 @@ ${question_id} 0 |
| 21 | 21 | Можливість оголосити однопредметний тендер |
| 22 | 22 | [Tags] ${USERS.users['${tender_owner}'].broker}: Можливість оголосити тендер |
| 23 | 23 | [Documentation] Створення закупівлі замовником, обовязково має повертати UAID закупівлі (номер тендера), |
| 24 | - ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${INITIAL_TENDER_DATA} | |
| 24 | + ${tender_data}= Підготовка початкових даних | |
| 25 | + ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${tender_data} | |
| 25 | 26 | ${LAST_MODIFICATION_DATE}= Get Current Date |
| 26 | 27 | Set To Dictionary ${TENDER} TENDER_UAID ${TENDER_UAID} |
| 27 | 28 | Set To Dictionary ${TENDER} LAST_MODIFICATION_DATE ${LAST_MODIFICATION_DATE} |
| ... | ... | @@ -289,7 +290,7 @@ ${question_id} 0 |
| 289 | 290 | [Documentation] |
| 290 | 291 | ... "shouldfail" argument as first switches the behaviour of keyword and "Викликати для учасника" to "fail if passed" |
| 291 | 292 | [Tags] ${USERS.users['${provider}'].broker}: Можливість задати запитання |
| 292 | - ${resp}= Викликати для учасника ${provider} Задати питання shouldfail ${TENDER['TENDER_UAID']} ${questions[${question_id}]} | |
| 293 | + ${resp}= Викликати для учасника ${provider} Задати питання shouldfail ${TENDER['TENDER_UAID']} ${QUESTIONS[${question_id}]} | |
| 293 | 294 | |
| 294 | 295 | Подати цінову пропозицію другим учасником |
| 295 | 296 | [Tags] ${USERS.users['${provider1}'].broker}: Можливість подати цінову пропозицію | ... | ... |
| ... | ... | @@ -19,7 +19,8 @@ ${broker} Quinta |
| 19 | 19 | Можливість оголосити однопредметний тендер |
| 20 | 20 | [Tags] ${USERS.users['${tender_owner}'].broker}: Можливість оголосити тендер |
| 21 | 21 | [Documentation] Створення закупівлі замовником, обовязково має повертати UAID закупівлі (номер тендера), |
| 22 | - ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${INITIAL_TENDER_DATA} | |
| 22 | + ${tender_data}= Підготовка початкових даних | |
| 23 | + ${TENDER_UAID}= Викликати для учасника ${tender_owner} Створити тендер ${tender_data} | |
| 23 | 24 | ${LAST_MODIFICATION_DATE}= Get Current Date |
| 24 | 25 | Set To Dictionary ${TENDER} TENDER_UAID ${TENDER_UAID} |
| 25 | 26 | Set To Dictionary ${TENDER} LAST_MODIFICATION_DATE ${LAST_MODIFICATION_DATE} | ... | ... |
Please
register
or
login
to post a comment