From f12c6ad24801d0f660b95408b1b1f63146bfaee0 Mon Sep 17 00:00:00 2001 From: Shtohryn Date: Thu, 1 May 2025 22:28:13 +0300 Subject: [PATCH 1/3] Update test_withdraw_preprint --- pages/preprints.py | 16 +++++++++++----- tests/test_preprints.py | 10 +++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/pages/preprints.py b/pages/preprints.py index a2a3358c..eeb456a4 100644 --- a/pages/preprints.py +++ b/pages/preprints.py @@ -225,7 +225,10 @@ class PreprintWithdrawPage(GuidBasePage, BasePreprintPage): By.CSS_SELECTOR, '[data-test-comment-input] textarea' ) request_withdrawal_button = Locator( - By.XPATH, '//div[@class="_Footer_gyio2l"]/button[text()="Withdraw"]' + By.CSS_SELECTOR, '[data-test-confirm-withdraw-button]' + ) + withdrawn_banner = Locator( + By.XPATH, "//span[normalize-space(text())='This preprint has been withdrawn.']" ) @@ -280,6 +283,7 @@ class PreprintDetailPage(GuidBasePage, BasePreprintPage): downloads_count = Locator(By.CSS_SELECTOR, '[data-test-download-count]') download_button = Locator(By.CSS_SELECTOR, '[data-test-download-button]') edit_preprint_button = Locator(By.CSS_SELECTOR, '[data-test-edit-preprint-button]') + withdraw_preprint_button = Locator(By.CSS_SELECTOR, '[data-test-withdrawal-button]') default_citation = Locator(By.CSS_SELECTOR, '[data-test-default-citation="apa"]') # Locators for the reviews app preprint detail page @@ -303,13 +307,15 @@ class PreprintDetailPage(GuidBasePage, BasePreprintPage): class PendingPreprintDetailPage(PreprintDetailPage): # This class is for preprints that are pending moderation identity = Locator( - By.ID, - 'preprintTitle', + By.CSS_SELECTOR, + '[data-test-preprint-title]', settings.LONG_TIMEOUT, ) # This locator needs a data-test-selector from software devs - # title = Locator(By.CSS_SELECTOR, '[data-test-preprint-title]', settings.LONG_TIMEOUT) - title = Locator(By.ID, 'preprintTitle', settings.LONG_TIMEOUT) + title = Locator( + By.CSS_SELECTOR, '[data-test-preprint-title]', settings.LONG_TIMEOUT + ) + # title = Locator(By.ID, 'preprintTitle', settings.LONG_TIMEOUT) class ReviewsDashboardPage(OSFBasePage): diff --git a/tests/test_preprints.py b/tests/test_preprints.py index 2a31aec6..f8336261 100644 --- a/tests/test_preprints.py +++ b/tests/test_preprints.py @@ -328,7 +328,7 @@ def test_edit_preprint(self, session, driver, preprint_detail_page): assert tag_found @markers.dont_run_on_prod - @pytest.mark.xfail(reason='https://openscience.atlassian.net/browse/ENG-6065') + # @pytest.mark.xfail(reason='https://openscience.atlassian.net/browse/ENG-6065') def test_withdraw_preprint(self, session, driver, preprint_detail_page): """Test the Withdraw Preprint functionality. Using the preprint_detail_page fixture we start on the Preprint Detail page for an api created preprint. Then @@ -341,7 +341,6 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): that the withdrawal request record is created. """ assert PreprintDetailPage(driver, verify=True) - preprint_detail_page.edit_preprint_button.click() edit_page = PreprintEditPage(driver) WebDriverWait(driver, 5).until( EC.element_to_be_clickable( @@ -363,8 +362,13 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): ) assert withdraw_page.request_withdrawal_button.is_enabled() withdraw_page.request_withdrawal_button.click() + WebDriverWait(driver, 5).until(EC.visibility_of(withdraw_page.withdrawn_banner)) # Should be redirected back to Preprint Detail page assert PendingPreprintDetailPage(driver, verify=True) + # Verify that "This preprint has been withdrawn." banner is displayed on Preprint Detail page. + assert ( + withdraw_page.withdrawn_banner.text == 'This preprint has been withdrawn.' + ) # Verify via the api that the Withdrawal Request record was created requests = osf_api.get_preprint_requests_records( node_id=preprint_detail_page.guid @@ -374,7 +378,7 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): record_found = False for request in requests: if request['attributes']['request_type'] == 'withdrawal': - assert request['attributes']['machine_state'] == 'pending' + assert request['attributes']['machine_state'] == 'accepted' record_found = True break if not record_found: From f8ecb90071ceccdf6138317dea727807d2ebf9eb Mon Sep 17 00:00:00 2001 From: Shtohryn Date: Thu, 29 May 2025 20:44:54 +0300 Subject: [PATCH 2/3] Add moderation actions --- api/osf_api.py | 39 ++++++++++++++++++++++++++++++++++++++- tests/test_preprints.py | 9 +++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/api/osf_api.py b/api/osf_api.py index f985e2e5..cdf5381b 100644 --- a/api/osf_api.py +++ b/api/osf_api.py @@ -46,7 +46,7 @@ def create_child_node( node_id=None, title='osf selenium child node', tags=None, - **kwargs + **kwargs, ): """Create a child node (a.k.a. component) of a given project node.""" if tags is None: @@ -863,6 +863,43 @@ def accept_moderated_preprint(session=None, preprint_node=None): ) +def get_preprint_id(session=None, preprint_node=None): + """Get priprint's id""" + if not session: + session = get_default_session() + request_url = f'/v2/preprints/{preprint_node}/requests/' + + response = session.get(url=request_url) + preprint_id = '' + for item in response.get('data', []): + preprint_id = item.get('id') + return preprint_id + + +def accept_withdraw_preprint(session=None, preprint_id=None): + """Accept a withdrawal request for a given preprint request ID.""" + if not session: + session = get_default_session() + review_url = '/v2/actions/requests/preprints/' + review_payload = { + 'data': { + 'type': 'preprint-request-actions', + 'attributes': { + 'trigger': 'accept', + 'comment': 'Preprint Withdraw Approval via OSF api', + }, + 'relationships': { + 'target': {'data': {'id': preprint_id, 'type': 'preprint-requests'}} + }, + } + } + session.post( + url=review_url, + item_type='review-actions', + raw_body=json.dumps(review_payload), + ) + + def create_preprint_withdrawal_request(session=None, preprint_node=None): """Create a withdrawal request for a given preprint node id.""" if not session: diff --git a/tests/test_preprints.py b/tests/test_preprints.py index f8336261..6e46c332 100644 --- a/tests/test_preprints.py +++ b/tests/test_preprints.py @@ -328,7 +328,6 @@ def test_edit_preprint(self, session, driver, preprint_detail_page): assert tag_found @markers.dont_run_on_prod - # @pytest.mark.xfail(reason='https://openscience.atlassian.net/browse/ENG-6065') def test_withdraw_preprint(self, session, driver, preprint_detail_page): """Test the Withdraw Preprint functionality. Using the preprint_detail_page fixture we start on the Preprint Detail page for an api created preprint. Then @@ -340,8 +339,11 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): user in the OSF admin app. The best we can do here is to verify through the api that the withdrawal request record is created. """ - assert PreprintDetailPage(driver, verify=True) edit_page = PreprintEditPage(driver) + assert PreprintDetailPage(driver, verify=True) + preprint_node = preprint_detail_page.url[len(settings.OSF_HOME) + 1 :] + osf_api.accept_moderated_preprint(session=None, preprint_node=preprint_node) + preprint_detail_page.goto() WebDriverWait(driver, 5).until( EC.element_to_be_clickable( (By.CSS_SELECTOR, '[data-test-withdrawal-button]') @@ -362,6 +364,9 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): ) assert withdraw_page.request_withdrawal_button.is_enabled() withdraw_page.request_withdrawal_button.click() + preprint_id = osf_api.get_preprint_id(session=None, preprint_node=preprint_node) + osf_api.accept_withdraw_preprint(session=None, preprint_id=preprint_id) + preprint_detail_page.goto() WebDriverWait(driver, 5).until(EC.visibility_of(withdraw_page.withdrawn_banner)) # Should be redirected back to Preprint Detail page assert PendingPreprintDetailPage(driver, verify=True) From 1c014d701aa31257793dabb850925a076fd0a34d Mon Sep 17 00:00:00 2001 From: Shtohryn Date: Thu, 5 Jun 2025 01:47:59 +0300 Subject: [PATCH 3/3] Fix: Replaced broken 'identity' locator to restore test stability --- pages/preprints.py | 4 ++-- tests/test_preprints.py | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pages/preprints.py b/pages/preprints.py index eeb456a4..a0da83eb 100644 --- a/pages/preprints.py +++ b/pages/preprints.py @@ -307,8 +307,8 @@ class PreprintDetailPage(GuidBasePage, BasePreprintPage): class PendingPreprintDetailPage(PreprintDetailPage): # This class is for preprints that are pending moderation identity = Locator( - By.CSS_SELECTOR, - '[data-test-preprint-title]', + By.ID, + 'preprintTitle', settings.LONG_TIMEOUT, ) # This locator needs a data-test-selector from software devs diff --git a/tests/test_preprints.py b/tests/test_preprints.py index 6e46c332..84eb2cdc 100644 --- a/tests/test_preprints.py +++ b/tests/test_preprints.py @@ -369,11 +369,9 @@ def test_withdraw_preprint(self, session, driver, preprint_detail_page): preprint_detail_page.goto() WebDriverWait(driver, 5).until(EC.visibility_of(withdraw_page.withdrawn_banner)) # Should be redirected back to Preprint Detail page - assert PendingPreprintDetailPage(driver, verify=True) + assert PreprintDetailPage(driver, verify=True) # Verify that "This preprint has been withdrawn." banner is displayed on Preprint Detail page. - assert ( - withdraw_page.withdrawn_banner.text == 'This preprint has been withdrawn.' - ) + assert withdraw_page.withdrawn_banner.is_displayed() # Verify via the api that the Withdrawal Request record was created requests = osf_api.get_preprint_requests_records( node_id=preprint_detail_page.guid