How to use _save_screenshot method in ATX

Best Python code snippet using ATX

test_all.py

Source:test_all.py Github

copy

Full Screen

...205 public_profile=False,206 screenshot_path=None):207 self.browser.get(self.base_url)208 log_in = self.browser.find_element_by_link_text('Log in')209 self._save_screenshot(screenshot_path, 'home_page', highlight=[log_in])210 log_in.click()211 self.browser.find_element_by_link_text('register').click()212 self._do_register_user(user_name, password, screenshot_path)213 if person_name is None:214 return215 self.browser.find_element_by_name('person_name').send_keys(person_name)216 if public_profile:217 self.browser.find_element_by_name('person_public').click()218 self.browser.find_element_by_name('single_email').send_keys(219 person_email)220 self._save_screenshot(screenshot_path, 'profile_new')221 self.browser.find_element_by_name('submit').click()222 self.assertIn('Your user profile has been saved.',223 self.browser.page_source)224 try:225 Select(226 self.browser.find_element_by_name('institution_id')227 ).select_by_visible_text('{}, {}'.format(228 institution_name, institution_country))229 self._save_screenshot(screenshot_path, 'profile_institution')230 self.browser.find_element_by_name('submit_select').click()231 self.assertIn('Your institution has been selected.',232 self.browser.page_source)233 except NoSuchElementException:234 self.browser.find_element_by_name('institution_name').send_keys(235 institution_name)236 Select(237 self.browser.find_element_by_name('country_code')238 ).select_by_visible_text(institution_country)239 self._save_screenshot(screenshot_path, 'profile_institution')240 self.browser.find_element_by_name('submit_add').click()241 self.assertIn('Your institution has been recorded.',242 self.browser.page_source)243 profile_link = self.browser.find_element_by_link_text(person_name)244 self._save_screenshot(screenshot_path, 'profile_complete',245 highlight=[profile_link, 'log_out_link'])246 profile_link.click()247 self._save_screenshot(screenshot_path, 'profile_view')248 def _do_register_user(self, user_name, password, screenshot_path=None):249 self.browser.find_element_by_name('user_name').send_keys(user_name)250 self.browser.find_element_by_name('password').send_keys(password)251 self.browser.find_element_by_name('password_check').send_keys(password)252 self._save_screenshot(screenshot_path, 'user_new')253 self.browser.find_element_by_name('submit').click()254 self.assertIn('Your user account has been created.',255 self.browser.page_source)256 def log_out_user(self):257 self.browser.find_element_by_link_text('log out').click()258 def log_in_user(self, user_name, password='password'):259 self.browser.get(self.base_url)260 log_in = self.browser.find_element_by_link_text('Log in')261 log_in.click()262 self.browser.find_element_by_name('user_name').send_keys(user_name)263 self.browser.find_element_by_name('password').send_keys(password)264 self.browser.find_element_by_name('submit').click()265 self.assertIn('You have been logged in.',266 self.browser.page_source)267 def set_up_facility(self, facility_code):268 self.browser.get(self.base_url + facility_code)269 facility_home_url = self.browser.current_url270 take_admin = self.browser.find_element_by_link_text('take admin')271 self._save_screenshot(self.admin_image_root, 'facility_home',272 [take_admin])273 take_admin.click()274 self.assertIn('You have taken administrative privileges.',275 self.browser.page_source)276 drop_admin = self.browser.find_element_by_link_text('drop admin')277 admin_menu = self.browser.find_element_by_link_text(278 'Administrative menu')279 self._save_screenshot(self.admin_image_root, 'facility_home_admin',280 [drop_admin, admin_menu])281 admin_menu.click()282 self._save_screenshot(self.admin_image_root, 'facility_admin_menu')283 admin_menu_url = self.browser.current_url284 # Create a new semester.285 semester_name = self._create_semester(286 'A', screenshot_path=self.admin_image_root)287 # Create a new queue.288 self.browser.get(admin_menu_url)289 self.browser.find_element_by_link_text('Queues').click()290 self.browser.find_element_by_link_text('New queue').click()291 queue_name = 'PI Science'292 self.browser.find_element_by_name('queue_name').send_keys(queue_name)293 self.browser.find_element_by_name('queue_code').send_keys('P')294 self.browser.find_element_by_name('description').send_keys(295 'This is the queue description.')296 self._save_screenshot(self.admin_image_root, 'queue_new')297 self.browser.find_element_by_name('submit').click()298 self.assertIn(299 'New queue "{}" has been added.'.format(queue_name),300 self.browser.page_source)301 affiliation_edit = self.browser.find_element_by_link_text(302 'Edit affiliations')303 self._save_screenshot(self.admin_image_root, 'queue_view',304 [affiliation_edit])305 affiliation_edit.click()306 affiliation_add = self.browser.find_element_by_id('add_affiliation')307 affiliation_add.click()308 affiliation_add.click()309 affiliation_add.click()310 self.browser.find_element_by_name('name_new_1').send_keys('China')311 self.browser.find_element_by_name('name_new_2').send_keys('Japan')312 self.browser.find_element_by_name('name_new_3').send_keys('Other')313 Select(314 self.browser.find_element_by_name('type_new_3')315 ).select_by_visible_text('Excluded')316 self._save_screenshot(self.admin_image_root, 'queue_affiliation',317 [affiliation_add])318 self.browser.find_element_by_name('submit').click()319 self.assertIn(320 'The affiliations have been updated.',321 self.browser.page_source)322 # Create a call.323 self.browser.get(admin_menu_url)324 self._create_call(325 'Regular', semester_name, screenshot_path=self.admin_image_root)326 # Add categories.327 self.browser.get(admin_menu_url)328 self.browser.find_element_by_link_text('Categories').click()329 category_add = self.browser.find_element_by_id('add_category')330 category_add.click()331 category_add.click()332 self.browser.find_element_by_name('name_new_1').send_keys(333 'Star formation')334 self.browser.find_element_by_name('name_new_2').send_keys(335 'Cosmology')336 self._save_screenshot(self.admin_image_root, 'category',337 [category_add])338 self.browser.find_element_by_name('submit').click()339 self.assertIn(340 'The categories have been updated.',341 self.browser.page_source)342 # Upload a MOC.343 self.browser.get(facility_home_url)344 self.browser.find_element_by_link_text('Clash Tool').click()345 self.browser.find_element_by_link_text('View all defined areas of sky coverage').click()346 self.browser.find_element_by_link_text('New coverage map').click()347 self.browser.find_element_by_name('name').send_keys('Example')348 self.browser.find_element_by_name('description').send_keys(349 'This area is part of the "..." survey and ...')350 # Give path to MOC assuming we are in the top level directory.351 self.browser.find_element_by_name('file').send_keys(352 self._get_example_path('example_moc.fits'))353 self._save_screenshot(self.admin_image_root, 'moc')354 self.browser.find_element_by_name('submit').click()355 self.assertIn(356 'The new coverage map has been stored.',357 self.browser.page_source)358 return (semester_name, queue_name)359 def _create_semester(self, suffix, screenshot_path=None):360 self.browser.find_element_by_link_text('Semesters').click()361 self.browser.find_element_by_link_text('New semester').click()362 # Make sure we are going to generate a semester which is open for363 # submissions: base it on the current date and use JCMT naming.364 current_date = datetime.utcnow()365 semester_year = str(current_date.year + 1)366 semester_name = semester_year[2:] + suffix367 self.browser.find_element_by_name('semester_name').send_keys(368 semester_name)369 self.browser.find_element_by_name('semester_code').send_keys(370 semester_name)371 self.browser.find_element_by_name('start_date').send_keys(372 semester_year + '-01-01')373 self.browser.find_element_by_name('start_time').send_keys(374 '00:00')375 self.browser.find_element_by_name('end_date').send_keys(376 semester_year + '-07-01')377 self.browser.find_element_by_name('end_time').send_keys(378 '00:00')379 self.browser.find_element_by_name('description').send_keys(380 'The instrumentation available is as follows ...')381 self._save_screenshot(screenshot_path, 'semester_new')382 self.browser.find_element_by_name('submit').click()383 self.assertIn(384 'New semester "{}" has been created.'.format(semester_name),385 self.browser.page_source)386 # Enter the call preamble.387 preamble_link = self.browser.find_element_by_id('preamble_edit_1')388 self._save_screenshot(389 screenshot_path, 'semester_view', [preamble_link])390 preamble_link.click()391 self.browser.find_element_by_name('description').send_keys(392 'We invite proposals ...')393 self._save_screenshot(screenshot_path, 'call_preamble')394 self.browser.find_element_by_name('submit').click()395 self.assertIn(396 'The regular call preamble for semester {} '397 'has been saved.'.format(semester_name),398 self.browser.page_source)399 return semester_name400 def _create_call(self, type_name, semester_name, screenshot_path=None):401 self.browser.find_element_by_link_text('Calls').click()402 self._save_screenshot(screenshot_path, 'call_list_empty',403 ['new_call_links'])404 self.browser.find_element_by_link_text(type_name).click()405 Select(406 self.browser.find_element_by_name('semester_id')407 ).select_by_visible_text(semester_name)408 current_date = datetime.utcnow()409 current_year = str(current_date.year)410 self.browser.find_element_by_name('open_date').send_keys(411 current_year + '-01-01')412 self.browser.find_element_by_name('open_time').send_keys(413 '00:00')414 self.browser.find_element_by_name('close_date').send_keys(415 current_year + '-12-31')416 self.browser.find_element_by_name('close_time').send_keys(417 '23:59')418 self._save_screenshot(screenshot_path, 'call_new')419 self.browser.find_element_by_name('submit').click()420 self.assertIn(421 'The new call has been added.',422 self.browser.page_source)423 def create_proposal(self, facility_code, semester_name):424 self.browser.get(self.base_url + facility_code)425 semester_link = self.browser.find_element_by_link_text(semester_name)426 self._save_screenshot(self.user_image_root, 'facility_home',427 [semester_link])428 semester_link.click()429 queue_link = self.browser.find_element_by_link_text(430 'Create a proposal for the PI Science Queue')431 self._save_screenshot(self.user_image_root, 'call_view', [queue_link])432 queue_link.click()433 Select(434 self.browser.find_element_by_name('affiliation_id')435 ).select_by_visible_text('China')436 self.browser.find_element_by_name('proposal_title').send_keys(437 'An Example Proposal')438 self._save_screenshot(self.user_image_root, 'proposal_new')439 self.browser.find_element_by_name('submit_new').click()440 self.assertIn(441 'Your new proposal has been created.',442 self.browser.page_source)443 self.browser.find_element_by_id('callout_dismiss').click()444 self._save_screenshot(445 self.user_image_root, 'proposal_view',446 ['submit_proposal_link', 'person_proposals_link',447 'proposal_identifier_cell'])448 proposal_url = self.browser.current_url449 # Add other members to the proposal.450 self.browser.find_element_by_link_text('Add member').click()451 Select(452 self.browser.find_element_by_name('person_id')453 ).select_by_visible_text(454 'Another Person, Test Institution, United States')455 for affiliation_selection in self.browser.find_elements_by_name(456 'affiliation_id'):457 Select(affiliation_selection).select_by_visible_text('Other')458 self._save_screenshot(self.user_image_root, 'member_add')459 self.browser.find_element_by_name('submit_link').click()460 self.assertIn(461 'has been added to the proposal.',462 self.browser.page_source)463 self.browser.find_element_by_link_text('Edit members').click()464 self.browser.find_element_by_name('observer_1').click()465 self._save_screenshot(self.user_image_root, 'member_edit')466 self.browser.find_element_by_name('submit').click()467 self.assertIn(468 'The proposal member list has been updated.',469 self.browser.page_source)470 self.browser.find_element_by_link_text('Edit student list').click()471 self.browser.find_element_by_name('student_2').click()472 self._save_screenshot(self.user_image_root, 'member_student')473 self.browser.find_element_by_name('submit').click()474 self.assertIn(475 'The list of students has been updated.',476 self.browser.page_source)477 self.browser.find_element_by_link_text('Add member').click()478 for affiliation_selection in self.browser.find_elements_by_name(479 'affiliation_id'):480 Select(affiliation_selection).select_by_visible_text('Other')481 self.browser.find_element_by_name('name').send_keys('Invited Member')482 self.browser.find_element_by_name('email').send_keys(483 'invitee@somewhere.edu')484 self.browser.find_element_by_name('submit_invite').click()485 self.assertIn(486 'has been added to the proposal.',487 self.browser.page_source)488 self.browser.find_element_by_name('institution_name').send_keys(489 'Your Institution')490 Select(491 self.browser.find_element_by_name('country_code')492 ).select_by_visible_text('United States')493 self.browser.find_element_by_name('submit_add').click()494 self.assertIn(495 'The institution has been recorded.',496 self.browser.page_source)497 # Try re-sending the invitation email.498 self.browser.find_element_by_link_text('Re-send invitation').click()499 self.assertIn(500 'Would you like to re-send an invitation',501 self.browser.page_source)502 self.browser.find_element_by_name('submit_confirm').click()503 self.assertIn(504 'has been re-invited to the proposal',505 self.browser.page_source)506 # Try submitting the proposal now -- this will generate errors,507 # and should not allow use to submit.508 self.browser.find_element_by_link_text('Submit proposal').click()509 self.assertIn(510 'Please correct the errors identified above before submitting',511 self.browser.page_source)512 with self.assertRaises(NoSuchElementException):513 self.browser.find_element_by_name('submit_confirm')514 self._save_screenshot(self.user_image_root, 'submit_error')515 self.browser.get(proposal_url)516 # Edit the title and abstract.517 self.browser.find_element_by_link_text('Edit title').click()518 self._save_screenshot(self.user_image_root, 'title_edit')519 self.browser.find_element_by_name('submit').click()520 # (Hedwig currently shows this flash message even if the title521 # didn't change.)522 self.assertIn(523 'The proposal title has been changed.',524 self.browser.page_source)525 self.browser.find_element_by_partial_link_text('Edit abstract').click()526 self.browser.find_element_by_name('category_1').click()527 self.browser.find_element_by_name('text').send_keys(528 'This is an example proposal.')529 self._save_screenshot(self.user_image_root, 'abstract_edit')530 self.browser.find_element_by_name('submit').click()531 self.assertIn(532 'The abstract has been saved.',533 self.browser.page_source)534 # Edit the public summary.535 self.browser.find_element_by_partial_link_text(536 'Edit public summary').click()537 self.browser.find_element_by_name('text').send_keys(538 'We are observing ...')539 self._save_screenshot(self.user_image_root, 'jcmt_pr_summary_edit')540 self.browser.find_element_by_name('submit').click()541 self.assertIn(542 'The public summary has been saved.',543 self.browser.page_source)544 # Create an observing request.545 self.browser.find_element_by_link_text(546 'Edit observing request').click()547 self.browser.find_element_by_id('add_request').click()548 Select(549 self.browser.find_element_by_name('instrument_new_1')550 ).select_by_visible_text('SCUBA-2')551 Select(552 self.browser.find_element_by_name('instrument_new_2')553 ).select_by_visible_text('HARP')554 Select(555 self.browser.find_element_by_name('weather_new_1')556 ).select_by_value('1')557 Select(558 self.browser.find_element_by_name('weather_new_2')559 ).select_by_value('5')560 self.browser.find_element_by_name('time_new_1').send_keys(4)561 self.browser.find_element_by_name('time_new_2').send_keys(12)562 self._save_screenshot(self.user_image_root, 'request_edit')563 self.browser.find_element_by_name('submit_save').click()564 self.assertIn(565 'The observing request has been saved.',566 self.browser.page_source)567 # Add a previous proposal.568 self.browser.find_element_by_partial_link_text(569 'Edit previous proposals').click()570 self.browser.find_element_by_name('code_new_1').send_keys('M00AI000')571 Select(572 self.browser.find_element_by_name('pub_type_0_new_1')573 ).select_by_visible_text('ADS bibcode')574 self.browser.find_element_by_name('publication_0_new_1').send_keys(575 '2013MNRAS.430.2513H')576 Select(577 self.browser.find_element_by_name('pub_type_1_new_1')578 ).select_by_visible_text('ADS bibcode')579 self.browser.find_element_by_name('publication_1_new_1').send_keys(580 '2013MNRAS.430.2534D')581 self._save_screenshot(self.user_image_root, 'prev_proposal')582 self.browser.find_element_by_name('submit').click()583 self.assertIn(584 'The previous proposals list has been saved.',585 self.browser.page_source)586 # Add target objects.587 self.browser.find_element_by_link_text('Edit targets').click()588 self.browser.find_element_by_id('add_target').click()589 # Place these targets in the name resolver proxy's fixed target list590 # so that we don't have to connect to CADC to resolve them.591 QueryView.add_fixed_name_response(592 'LDN 123', '{"target":"LDN 123","service":"Hedwig(fixed)",'593 '"coordsys":"ICRS","ra":271.9,"dec":-27.4167,"time":1}')594 QueryView.add_fixed_name_response(595 'LDN 456', '{"target":"LDN 456","service":"Hedwig(fixed)",'596 '"coordsys":"ICRS","ra":283.2,"dec":-10.9333,"time":0}')597 self.browser.find_element_by_name('name_new_1').send_keys('LDN 123')598 self.browser.find_element_by_name('name_new_2').send_keys('LDN 456')599 self.browser.find_element_by_id('resolve_new_1').click()600 self.browser.find_element_by_id('resolve_new_2').click()601 self.browser.find_element_by_name('time_new_1').send_keys('8')602 self.browser.find_element_by_name('time_new_2').send_keys('8')603 self.browser.find_element_by_name('priority_new_1').send_keys('1')604 self.browser.find_element_by_name('priority_new_2').send_keys('2')605 # Wait for the resolver to finish.606 wait = WebDriverWait(self.browser, 10)607 wait.until(expected_conditions.text_to_be_present_in_element_value((608 By.NAME, 'x_new_1'), ':'))609 wait.until(expected_conditions.text_to_be_present_in_element_value((610 By.NAME, 'x_new_2'), ':'))611 self.assertTrue(self.browser.find_element_by_name(612 'x_new_1').get_attribute('value').startswith('18:07:'))613 self.assertTrue(self.browser.find_element_by_name(614 'y_new_1').get_attribute('value').startswith('-27:25:'))615 self.assertTrue(self.browser.find_element_by_name(616 'x_new_2').get_attribute('value').startswith('18:52:'))617 self.assertTrue(self.browser.find_element_by_name(618 'y_new_2').get_attribute('value').startswith('-10:55:'))619 self._save_screenshot(self.user_image_root, 'target_edit')620 self.browser.find_element_by_name('submit').click()621 self.assertIn(622 'The target object list has been saved.',623 self.browser.page_source)624 self.browser.find_element_by_link_text('Upload target list').click()625 self.assertIn(626 'A target list can be uploaded as a plain text file',627 self.browser.page_source)628 self._save_screenshot(self.user_image_root, 'target_upload')629 self.browser.get(proposal_url)630 self.browser.find_element_by_link_text('Clash Tool').click()631 self._save_screenshot(self.user_image_root, 'target_clash')632 self.browser.find_element_by_link_text('Back to proposal').click()633 self.browser.find_element_by_link_text('Target Availability').click()634 self._save_screenshot(self.user_image_root, 'target_avail')635 self.browser.find_element_by_link_text('Back to proposal').click()636 self.browser.find_element_by_link_text('Edit note').click()637 self.browser.find_element_by_name('text').send_keys(638 'I used the clash tool and I found ...')639 self._save_screenshot(self.user_image_root, 'target_note')640 self.browser.find_element_by_name('submit').click()641 self.assertIn(642 'The note on tool results has been saved.',643 self.browser.page_source)644 # Add an integration time calculation.645 self._add_itc_calculation(646 screenshot_path=self.user_image_root,647 highlight_extra=['main_result_table', 'perm_query_link'])648 # Edit technical justification.649 self.browser.find_element_by_link_text(650 'Edit technical justification').click()651 edit_text_link = self.browser.find_element_by_link_text('Edit text')652 upload_pdf_link = self.browser.find_element_by_link_text(653 'Upload new PDF file')654 self._save_screenshot(self.user_image_root, 'tech_case_edit',655 [edit_text_link, upload_pdf_link])656 upload_pdf_link.click()657 self.assertIn(658 'Upload Technical Justification PDF',659 self.browser.page_source)660 self._save_screenshot(self.user_image_root, 'tech_case_pdf')661 self.browser.find_element_by_name('file').send_keys(662 self._get_example_path('example_justification.pdf'))663 self.browser.find_element_by_name('submit').click()664 self.assertIn(665 'The technical justification has been uploaded.',666 self.browser.page_source)667 self.assertIn(668 'Not yet processed',669 self.browser.page_source)670 n_processed = process_proposal_pdf(db=self.db)671 self.assertEqual(n_processed, 1)672 self.browser.get(self.browser.current_url)673 self.assertIn(674 'Processed successfully',675 self.browser.page_source)676 self._save_screenshot(self.user_image_root, 'tech_case_pdf_uploaded')677 self.browser.find_element_by_link_text('Edit text').click()678 self.browser.find_element_by_name('text').send_keys(679 'We plan to observe ...')680 self._save_screenshot(self.user_image_root, 'tech_case_text',681 ['text_words'])682 self.browser.find_element_by_name('submit').click()683 self.assertIn(684 'The technical justification has been saved.',685 self.browser.page_source)686 self.browser.find_element_by_link_text('Back to proposal').click()687 # Edit scientific justification.688 self.browser.find_element_by_link_text(689 'Edit scientific justification').click()690 self._add_figure(691 screenshot_path=self.user_image_root,692 screenshot_prefix='sci_case')693 manage_figures = self.browser.find_element_by_link_text(694 'Manage figures')695 self._save_screenshot(self.user_image_root, 'sci_case_edit',696 [manage_figures, 'edit_figure_1_link'])697 self.browser.find_element_by_link_text('Edit text').click()698 self.browser.find_element_by_name('text').send_keys(699 'The scientific rationale for this project is ...')700 self._save_screenshot(self.user_image_root, 'sci_case_text',701 ['text_words'])702 self.browser.find_element_by_name('submit').click()703 self.assertIn(704 'The scientific justification has been saved.',705 self.browser.page_source)706 self.browser.find_element_by_link_text('Back to proposal').click()707 # Submit the proposal (should stay at the end to minimize warnings708 # on the submission page).709 self._submit_proposal(screenshot_path=self.user_image_root)710 self.browser.find_element_by_link_text('Validate proposal').click()711 self._save_screenshot(self.user_image_root, 'validate')712 self.browser.find_element_by_link_text('Back to proposal').click()713 # Grab a screenshot of the complete proposal now.714 self._save_screenshot(self.user_image_root, 'proposal_complete',715 ['proposal_status_cell'])716 self.browser.find_element_by_link_text('Withdraw proposal').click()717 self._save_screenshot(self.user_image_root, 'withdraw')718 self.browser.find_element_by_name('submit_confirm').click()719 self.assertIn(720 'The proposal has been withdrawn.',721 self.browser.page_source)722 # Re-submit the proposal so that we can use it to test the review723 # system later.724 self._submit_proposal()725 # Test more source list upload.726 self.browser.find_element_by_link_text('Upload target list').click()727 self.browser.find_element_by_name('file').send_keys(728 self._get_example_path('example_list.txt'))729 self.browser.find_element_by_name('submit').click()730 self.assertIn(731 'The target object list has been updated.',732 self.browser.page_source)733 self.assertIn('LDN 123', self.browser.page_source)734 self.assertIn('LDN 456', self.browser.page_source)735 self.assertIn('NGC 1234', self.browser.page_source)736 def _submit_proposal(self, screenshot_path=None):737 self.browser.find_element_by_link_text('Submit proposal').click()738 self._save_screenshot(screenshot_path, 'submit_ok')739 self.browser.find_element_by_name('submit_confirm').click()740 self.assertIn(741 'The proposal has been submitted.',742 self.browser.page_source)743 def _add_figure(744 self,745 screenshot_path=None,746 screenshot_prefix='component',747 is_review=False):748 current_url = self.browser.current_url749 self.browser.find_element_by_link_text('Upload new figure').click()750 self.browser.find_element_by_name('text').send_keys(751 'An example figure showing ...')752 self._save_screenshot(753 screenshot_path, '{}_{}'.format(screenshot_prefix, 'fig'))754 self.browser.find_element_by_name('file').send_keys(755 self._get_example_path('example_figure.png'))756 self.browser.find_element_by_name('submit').click()757 # Process the uploaded figure and reload.758 if is_review:759 n_processed = process_review_figure(db=self.db)760 else:761 n_processed = process_proposal_figure(db=self.db)762 self.assertEqual(n_processed, 1)763 self.browser.get(current_url)764 manage_figures = self.browser.find_element_by_link_text(765 'Manage figures')766 manage_figures.click()767 self._save_screenshot(768 screenshot_path, '{}_{}'.format(screenshot_prefix, 'fig_manage'))769 self.browser.find_element_by_name('submit').click()770 def _add_itc_calculation(771 self, screenshot_path=None,772 sensitivity='1.343', title='SCUBA-2 observation of LDN 456',773 save_prefix='', highlight_extra=[]):774 self.browser.find_element_by_link_text('SCUBA-2 ITC').click()775 position = self.browser.find_element_by_name('pos')776 position.clear()777 position.send_keys('-10')778 rms = self.browser.find_element_by_name('rms')779 rms.clear()780 rms.send_keys(sensitivity)781 self.browser.find_element_by_name('submit_calc').click()782 self.assertIn(783 'Results',784 self.browser.page_source)785 self.browser.find_element_by_name(786 '{}calculation_title'.format(save_prefix)).send_keys(title)787 submit_save_redir = self.browser.find_element_by_name(788 '{}submit_save_redir'.format(save_prefix))789 self._save_screenshot(790 screenshot_path, 'calc_scuba2',791 [submit_save_redir] + highlight_extra)792 submit_save_redir.click()793 self.assertIn(794 'The calculation has been saved',795 self.browser.page_source)796 self.browser.find_element_by_link_text('Manage calculations').click()797 self.assertIn(798 'Calculator: SCUBA-2 ITC',799 self.browser.page_source)800 self._save_screenshot(screenshot_path, 'calc_manage')801 self.browser.find_element_by_name('submit').click()802 def view_person_proposals(self):803 # Test the personal proposal list.804 self.browser.get(self.base_url + 'proposals')805 self.assertIn(806 '<h1>Your Proposals</h1>',807 self.browser.page_source)808 self.assertIn(809 'An Example Proposal',810 self.browser.page_source)811 self._save_screenshot(self.user_image_root, 'proposal_list')812 def accept_invitation(self, user_name='invitee', screenshot_path=None):813 # Determine the invitation token to use.814 with self.db._transaction() as conn:815 token = conn.execute(select([invitation.c.token])).scalar()816 self.browser.get(self.base_url)817 self.browser.find_element_by_link_text(818 'Enter an invitation code').click()819 self.browser.find_element_by_name('token').send_keys(token)820 self._save_screenshot(screenshot_path, 'invitation_enter')821 self.browser.find_element_by_name('submit').click()822 self.assertIn(823 'Please log in or register for an account to proceed.',824 self.browser.page_source)825 register_link = self.browser.find_element_by_link_text('register')826 self._save_screenshot(screenshot_path, 'log_in_register',827 [register_link])828 register_link.click()829 self._do_register_user(user_name, 'password')830 self._save_screenshot(screenshot_path, 'invitation_accept')831 self.browser.find_element_by_name('submit_accept').click()832 self.assertIn(833 'The invitation has been accepted successfully.',834 self.browser.page_source)835 def remove_self(self):836 # Now remove self from the proposal.837 self.browser.find_element_by_link_text(838 'Remove yourself from this proposal').click()839 self.assertIn(840 'Are you sure you wish to remove yourself',841 self.browser.page_source)842 self.browser.find_element_by_name('submit_confirm').click()843 self.assertIn(844 'You have been removed from proposal',845 self.browser.page_source)846 def manage_account(self):847 # Go to the home page to loose any flashed message box.848 self.browser.get(self.base_url)849 profile_link = self.browser.find_element_by_id('user_profile_link')850 self._save_screenshot(self.user_image_root, 'profile_link',851 [profile_link])852 profile_link.click()853 self._save_screenshot(854 self.user_image_root, 'profile_edit_links',855 ['account_manage_links', 'profile_manage_links',856 self.browser.find_element_by_link_text('verify')])857 # Change password.858 self.browser.find_element_by_link_text('Change password').click()859 self.browser.find_element_by_name('password').send_keys('password')860 self.browser.find_element_by_name('password_new').send_keys(861 'new-pass')862 self.browser.find_element_by_name('password_check').send_keys(863 'new-pass')864 self._save_screenshot(self.user_image_root, 'password_change')865 self.browser.find_element_by_name('submit').click()866 self.assertIn(867 'Your password has been changed.',868 self.browser.page_source)869 # Change user name.870 self.browser.find_element_by_link_text('Change user name').click()871 user_name_box = self.browser.find_element_by_name('user_name')872 user_name_box.clear()873 user_name_box.send_keys('newusername')874 self.browser.find_element_by_name('password').send_keys('new-pass')875 self._save_screenshot(self.user_image_root, 'user_name_change')876 self.browser.find_element_by_name('submit').click()877 self.assertIn(878 'Your user name has been changed.',879 self.browser.page_source)880 # Edit profile.881 self.browser.find_element_by_link_text('Edit profile').click()882 self.assertIn(883 'Show in directory',884 self.browser.page_source)885 self._save_screenshot(self.user_image_root, 'profile_edit')886 self.browser.find_element_by_name('submit').click()887 self.assertIn(888 'Your user profile has been saved.',889 self.browser.page_source)890 # Edit email addresses.891 self.browser.find_element_by_link_text('Edit email addresses').click()892 self.assertIn(893 'not verified',894 self.browser.page_source)895 self._save_screenshot(self.user_image_root, 'email_edit',896 ['delete_2', 'add_email'])897 self.browser.find_element_by_name('submit').click()898 self.assertIn(899 'Your email addresses have been updated.',900 self.browser.page_source)901 # Verify email address.902 self.browser.find_element_by_link_text('verify').click()903 self.assertIn(904 'You can verify your address by sending a verification',905 self.browser.page_source)906 self.browser.find_element_by_name('submit_sent').click()907 self.assertIn(908 'Your address verification code has been sent by email to',909 self.browser.page_source)910 with self.db._transaction() as conn:911 token = conn.execute(select([verify_token.c.token])).scalar()912 self.browser.find_element_by_name('token').send_keys(token)913 self.browser.find_element_by_name('submit').click()914 self.assertIn(915 'Your email address example@somewhere.edu has been verified.',916 self.browser.page_source)917 # Change institution.918 self.browser.find_element_by_link_text('Change institution').click()919 self.assertIn(920 'If you would like to make minor corrections',921 self.browser.page_source)922 self.browser.find_element_by_name('institution_name').send_keys(923 'Another Institution')924 Select(925 self.browser.find_element_by_name('country_code')926 ).select_by_visible_text('United States')927 self._save_screenshot(self.user_image_root, 'institution_change')928 self.browser.find_element_by_name('submit_add').click()929 self.assertIn(930 'Your institution has been recorded.',931 self.browser.page_source)932 self.browser.find_element_by_link_text('Change institution').click()933 Select(934 self.browser.find_element_by_name('institution_id')935 ).select_by_visible_text(936 'Test Institution, United States')937 self.browser.find_element_by_name('submit_select').click()938 self.assertIn(939 'Your institution has been selected.',940 self.browser.page_source)941 # View institution.942 self.browser.find_element_by_partial_link_text(943 'View this institution').click()944 edit_institution = self.browser.find_element_by_link_text(945 'Edit this institution')946 self._save_screenshot(self.user_image_root, 'institution_view',947 [edit_institution])948 edit_institution.click()949 self.assertIn(950 'Are you sure you want to edit this institution?',951 self.browser.page_source)952 self.browser.find_element_by_name('submit_confirm').click()953 self._save_screenshot(self.user_image_root, 'institution_edit')954 self.browser.find_element_by_name('submit_edit').click()955 self.assertIn(956 'The institution\'s record has been updated.',957 self.browser.page_source)958 # Institution list.959 self.browser.find_element_by_link_text('Institutions').click()960 self.assertIn(961 '<h1>Institutions</h1>',962 self.browser.page_source)963 # User directory.964 self.browser.find_element_by_id('user_profile_link').click()965 self.browser.find_element_by_link_text('User Directory').click()966 self.assertIn(967 '<h1>Directory of Users</h1>',968 self.browser.page_source)969 def reset_password(self):970 self.browser.find_element_by_link_text('Log in').click()971 reset_password = self.browser.find_element_by_link_text(972 'reset your password')973 self._save_screenshot(self.user_image_root, 'pass_reset_link',974 [reset_password])975 reset_password.click()976 self.browser.find_element_by_name('email').send_keys(977 'example@somewhere.edu')978 self._save_screenshot(self.user_image_root, 'pass_reset_get')979 self.browser.find_element_by_name('submit').click()980 self.assertIn(981 'Your password reset code has been sent',982 self.browser.page_source)983 with self.db._transaction() as conn:984 token = conn.execute(select([reset_token.c.token])).scalar()985 self.browser.find_element_by_name('token').send_keys(token)986 self.browser.find_element_by_name('password').send_keys(987 'password')988 self.browser.find_element_by_name('password_check').send_keys(989 'password')990 self._save_screenshot(self.user_image_root, 'pass_reset_use')991 self.browser.find_element_by_name('submit').click()992 self.assertIn(993 'Your password has been changed.',994 self.browser.page_source)995 def administer_facility(self, facility_code, semester_name, queue_name):996 """997 This test performs some administrative tasks on a facility.998 It takes a screenshot of the call proposals list and so is intended999 to run after a user has created a proposal.1000 It also alters the closing date of the call so that it is no longer1001 open.1002 """1003 self.browser.get(self.base_url + facility_code)1004 facility_home_url = self.browser.current_url1005 self.browser.find_element_by_link_text('take admin').click()1006 self.browser.find_element_by_link_text('Administrative menu').click()1007 admin_menu_url = self.browser.current_url1008 # Go to the call list and get screenshots of the list and the1009 # list of proposals.1010 self.browser.find_element_by_link_text('Calls').click()1011 self._save_screenshot(self.admin_image_root, 'call_list')1012 self.browser.find_element_by_link_text(queue_name).click()1013 self.assertIn('<h1>Call:',1014 self.browser.page_source)1015 self.browser.find_element_by_link_text('Edit call').click()1016 # Set the closing date back to the start of the year.1017 current_date = datetime.utcnow()1018 current_year = str(current_date.year)1019 close_date = self.browser.find_element_by_name('close_date')1020 close_date.clear()1021 close_date.send_keys(current_year + '-01-01')1022 close_time = self.browser.find_element_by_name('close_time')1023 close_time.clear()1024 close_time.send_keys('00:01')1025 self.browser.find_element_by_name('submit').click()1026 self.assertIn('The call has been updated.',1027 self.browser.page_source)1028 self.browser.find_element_by_link_text('View proposals').click()1029 self.assertIn('<h1>Proposals:',1030 self.browser.page_source)1031 self._save_screenshot(self.admin_image_root, 'call_proposals')1032 # Go to a proposal to correct the affiliation information.1033 self.browser.find_element_by_id('proposal_view_1').click()1034 edit_link = self.browser.find_element_by_id('member_aff_ed_2')1035 self._save_screenshot(self.admin_image_root, 'proposal_mem_aff_link',1036 [edit_link, 'alter_state_link'])1037 edit_link.click()1038 Select(1039 self.browser.find_element_by_name('affiliation_id')1040 ).select_by_visible_text('Japan')1041 self._save_screenshot(self.admin_image_root, 'proposal_mem_aff_edit')1042 self.browser.find_element_by_name('submit').click()1043 self.assertIn(1044 'The affiliation has been updated.',1045 self.browser.page_source)1046 edit_link = self.browser.find_element_by_id('alter_state_link').click()1047 self._save_screenshot(self.admin_image_root, 'proposal_alter_state')1048 self.browser.find_element_by_name('submit').click()1049 self.assertIn(1050 'The proposal state has been updated.',1051 self.browser.page_source)1052 # Try deleting the MOC.1053 self.browser.get(facility_home_url)1054 self.browser.find_element_by_link_text('Clash Tool').click()1055 self.browser.find_element_by_link_text('View all defined areas of sky coverage').click()1056 self.browser.find_element_by_link_text('Delete').click()1057 self.browser.find_element_by_name('submit_confirm').click()1058 self.assertIn('The coverage map has been deleted.',1059 self.browser.page_source)1060 # Also test the semester and queue edit pages.1061 self.browser.get(admin_menu_url)1062 self.browser.find_element_by_link_text('Semesters').click()1063 self.browser.find_element_by_link_text(semester_name).click()1064 self.browser.find_element_by_link_text('Edit semester').click()1065 self.browser.find_element_by_name('submit').click()1066 self.assertIn('Semester "{}" has been updated.'.format(semester_name),1067 self.browser.page_source)1068 self.browser.find_element_by_link_text('Administrative menu').click()1069 self.browser.find_element_by_link_text('Queues').click()1070 self.browser.find_element_by_link_text('PI Science').click()1071 self.browser.find_element_by_link_text('Edit queue').click()1072 self.browser.find_element_by_name('submit').click()1073 self.assertIn('Queue "PI Science" has been updated.',1074 self.browser.page_source)1075 # Set up the review groups.1076 admin_queue_url = self.browser.current_url1077 for (group_name, group_abbr, group_members) in (1078 ('Committee members', 'cttee', (1079 'Example Group Member', 'Another Group Member')),1080 ('Technical assessors', 'tech', (1081 'Example Technical Assessor',))):1082 self.browser.get(admin_queue_url)1083 self.browser.find_element_by_link_text(group_name).click()1084 first_person = True1085 for person_name in group_members:1086 self.browser.find_element_by_link_text('Add member').click()1087 Select(1088 self.browser.find_element_by_name('person_id')1089 ).select_by_visible_text(1090 '{}, Test Institution, United States'.format(person_name))1091 if first_person:1092 self._save_screenshot(self.admin_image_root,1093 'group_{}_add'.format(group_abbr))1094 self.browser.find_element_by_name('submit_link').click()1095 self.assertIn(1096 '{} has been added to the group.'.format(person_name),1097 self.browser.page_source)1098 first_person = False1099 # Reload page to remove the yellow flash box for the screenshot.1100 self.browser.get(self.browser.current_url)1101 self._save_screenshot(self.admin_image_root,1102 'group_{}'.format(group_abbr))1103 self.browser.find_element_by_link_text('Edit members').click()1104 self._save_screenshot(self.admin_image_root,1105 'group_{}_edit'.format(group_abbr))1106 self.browser.find_element_by_name('submit').click()1107 self.assertIn('The group membership has been saved.',1108 self.browser.page_source)1109 # Go back to the main page and test the "drop admin" link.1110 self.browser.get(self.base_url)1111 self.browser.find_element_by_link_text('drop admin').click()1112 self.assertIn('You have dropped administrative privileges.',1113 self.browser.page_source)1114 def set_up_review(self, facility_code):1115 """1116 This test sets up a review process.1117 """1118 self.browser.get(self.base_url + facility_code)1119 self.browser.find_element_by_link_text('take admin').click()1120 self.browser.find_element_by_link_text('Administrative menu').click()1121 self.browser.find_element_by_link_text('Calls').click()1122 self.browser.find_element_by_link_text('Review process').click()1123 self._save_screenshot(self.admin_image_root, 'review_process')1124 # Set review deadlines.1125 self.browser.find_element_by_link_text(1126 'Edit review deadlines').click()1127 self.browser.find_element_by_name('date_date_2').send_keys('2020-01-01')1128 self.browser.find_element_by_name('date_time_2').send_keys('00:00')1129 self._save_screenshot(self.admin_image_root, 'review_deadline')1130 self.browser.find_element_by_name('submit').click()1131 self.assertIn('The review deadlines have been saved.',1132 self.browser.page_source)1133 # Add an external reviewer.1134 self.browser.find_element_by_link_text('Assign reviewers').click()1135 self._save_screenshot(1136 self.admin_image_root, 'reviewer_assign',1137 ['assign_reviewer_links'])1138 self.browser.find_element_by_link_text('Add external reviewer').click()1139 self.browser.find_element_by_name('name').send_keys('Invited Reviewer')1140 self.browser.find_element_by_name('email').send_keys(1141 'reviewer@somewhere.edu')1142 self._save_screenshot(self.admin_image_root, 'reviewer_external', [1143 'review_deadline_cell'])1144 self.browser.find_element_by_name('submit_invite').click()1145 self.assertIn(1146 'Invited Reviewer has been invited to register.',1147 self.browser.page_source)1148 Select(1149 self.browser.find_element_by_name('institution_id')1150 ).select_by_visible_text(1151 'Test Institution, United States')1152 self.browser.find_element_by_name('submit_select').click()1153 self.assertIn(1154 'The institution has been selected.',1155 self.browser.page_source)1156 # Technical reviewers page.1157 self.browser.find_element_by_link_text(1158 'Assign technical assessors').click()1159 self.browser.find_elements_by_name('rev_{}_1'.format(1160 BaseReviewerRole.TECH))[0].click()1161 self._save_screenshot(self.admin_image_root, 'reviewer_tech')1162 self.browser.find_element_by_name('submit').click()1163 self.assertIn('assignments have been updated.',1164 self.browser.page_source)1165 # Committee reviewers page.1166 self.browser.find_element_by_link_text(1167 'Assign committee members').click()1168 self.browser.find_elements_by_name('rev_{}_1'.format(1169 BaseReviewerRole.CTTEE_PRIMARY))[1].click()1170 self.browser.find_elements_by_name('rev_{}_1'.format(1171 BaseReviewerRole.CTTEE_SECONDARY))[0].click()1172 self._save_screenshot(self.admin_image_root, 'reviewer_cttee')1173 self.browser.find_element_by_name('submit').click()1174 self.assertIn('assignments have been updated.',1175 self.browser.page_source)1176 # Sending notifications.1177 self.browser.refresh()1178 self._save_screenshot(1179 self.admin_image_root, 'reviewer_assign_filled',1180 ['notify_reviewer_links'])1181 self.browser.find_element_by_link_text(1182 'Notify technical assessors').click()1183 self._save_screenshot(self.admin_image_root, 'reviewer_tech_notify')1184 self.browser.find_element_by_name('submit_confirm').click()1185 self.assertIn('Notifications have been sent',1186 self.browser.page_source)1187 def set_up_peer_review(self, facility_code):1188 self.browser.get(self.base_url + facility_code)1189 self.browser.find_element_by_link_text('take admin').click()1190 self.browser.find_element_by_link_text('rapid turnaround').click()1191 # Set review deadlines.1192 self.browser.find_element_by_link_text(1193 'Edit review deadlines').click()1194 self.browser.find_element_by_name('date_date_7').send_keys('2020-01-01')1195 self.browser.find_element_by_name('date_time_7').send_keys('00:00')1196 self.browser.find_element_by_name('submit').click()1197 self.assertIn('The review deadlines have been saved.',1198 self.browser.page_source)1199 # Assign peer reviewers.1200 self.browser.find_element_by_link_text('Assign reviewers').click()1201 self.browser.find_element_by_link_text('Assign peer reviewers').click()1202 for checkbox in self.browser.find_elements_by_css_selector(1203 'input[type="checkbox"]'):1204 checkbox.click()1205 self.browser.find_element_by_name('submit').click()1206 self.assertIn('assignments have been updated.',1207 self.browser.page_source)1208 def enter_technical_assessment(self):1209 """1210 Tests entering a technical assessment.1211 """1212 # Navigate to the technical assessment.1213 self.browser.find_element_by_link_text('Your reviews').click()1214 self.browser.find_element_by_link_text('Technical').click()1215 # Add a calculation.1216 self._add_itc_calculation(1217 screenshot_path=self.review_image_root,1218 sensitivity='1.434', title='Adjusted sensitivity',1219 save_prefix='review_')1220 # Add a figure.1221 self._add_figure(1222 screenshot_path=self.review_image_root,1223 screenshot_prefix='tech_assess',1224 is_review=True)1225 # Fill in the review.1226 self.browser.find_element_by_name('text').send_keys(1227 'My assessment of the feasibility of this proposal is...')1228 Select(1229 self.browser.find_element_by_name('assessment')1230 ).select_by_visible_text('Feasible')1231 self.browser.find_element_by_name('done').click()1232 self._save_screenshot(self.review_image_root, 'tech_assess_edit',1233 ['add_calc_links', 'upload_fig_link'])1234 self.browser.find_element_by_name('submit').click()1235 self.assertIn(1236 'The review has been saved and marked as done.',1237 self.browser.page_source)1238 def enter_review(self):1239 """1240 Tests entering a review.1241 Assumes that the person starts on their review information page1242 after accepting an invitation.1243 """1244 self._save_screenshot(self.review_image_root, 'review_info',1245 ['person_reviews_link', 'review_action_links'])1246 self.browser.find_element_by_link_text('Write your review').click()1247 self.browser.find_element_by_name('jcmt_review_aims').send_keys(1248 'The aims of this proposal ...')1249 self.browser.find_element_by_name('jcmt_review_goals').send_keys(1250 'The goals of this proposal ...')1251 self.browser.find_element_by_name(1252 'jcmt_review_difficulties').send_keys(1253 'Difficulties with this proposal are ...')1254 Select(1255 self.browser.find_element_by_name('jcmt_rating_justification')1256 ).select_by_visible_text('Convincing and well described')1257 self.browser.find_element_by_name('jcmt_review_details').send_keys(1258 'The technical details in this program ...')1259 self.browser.find_element_by_name('jcmt_review_obj_inst').send_keys(1260 'The target objects and instrumentation ...')1261 self.browser.find_element_by_name('jcmt_review_telescope').send_keys(1262 'The choice of telescope for this proposal is ...')1263 Select(1264 self.browser.find_element_by_name('jcmt_rating_technical')1265 ).select_by_visible_text('Correct and well described')1266 Select(1267 self.browser.find_element_by_name('jcmt_rating_urgency')1268 ).select_by_visible_text('Timely and competitive: must be done now')1269 self.browser.find_element_by_name('text').send_keys(1270 'My opinion of this proposal is...')1271 self.browser.find_element_by_name('rating').send_keys('50')1272 self.browser.find_element_by_name('done').click()1273 self._save_screenshot(self.review_image_root, 'review_edit')1274 self.browser.find_element_by_name('submit').click()1275 self.assertIn(1276 'The review has been saved and marked as done.',1277 self.browser.page_source)1278 def enter_cttee_review(1279 self, role_name, rating, expertise, screenshot_path=None):1280 """1281 Tests entering a committee member's.1282 """1283 # Navigate to the review.1284 self.browser.find_element_by_link_text('Your reviews').click()1285 self.browser.find_element_by_link_text(role_name).click()1286 # Fill in the review.1287 self.browser.find_element_by_name('text').send_keys(1288 'My {} review is as follows...'.format(role_name))1289 self.browser.find_element_by_name('rating').send_keys(rating)1290 Select(1291 self.browser.find_element_by_name('jcmt_expertise')1292 ).select_by_visible_text(expertise)1293 self.browser.find_element_by_name('done').click()1294 self._save_screenshot(screenshot_path, 'cttee_review_edit')1295 self.browser.find_element_by_name('submit').click()1296 self.assertIn(1297 'The review has been saved and marked as done.',1298 self.browser.page_source)1299 def enter_peer_review(self):1300 self.browser.find_element_by_link_text('Your reviews').click()1301 self.browser.find_element_by_link_text('Peer').click()1302 Select(1303 self.browser.find_element_by_name('accepted')1304 ).select_by_value('1')1305 self._save_screenshot(self.review_image_root, 'peer_review_accept')1306 self.browser.find_element_by_name('submit').click()1307 self.assertIn(1308 'The review has been accepted.',1309 self.browser.page_source)1310 # Reload page to remove the yellow flash box for the screenshot.1311 self.browser.get(self.browser.current_url)1312 self._save_screenshot(self.review_image_root, 'peer_review_edit')1313 def view_person_reviews(self):1314 # Now acquire a screenshot of the "Your reviews" page.1315 self.browser.find_element_by_link_text('Your reviews').click()1316 self.assertIn('<h1>Your Reviews</h1>', self.browser.page_source)1317 self.assertIn('An Example Proposal', self.browser.page_source)1318 self.assertIn('External', self.browser.page_source)1319 self._save_screenshot(self.review_image_root, 'review_list')1320 def view_proposal_reviews(self, facility_code):1321 self.browser.find_element_by_link_text('take admin').click()1322 self.browser.get(self.base_url + facility_code)1323 self.browser.find_element_by_link_text('Administrative menu').click()1324 self.browser.find_element_by_link_text('Calls').click()1325 self.browser.find_element_by_link_text('Review process').click()1326 review_process_url = self.browser.current_url1327 # Enter affiliation weights.1328 self.browser.find_element_by_link_text(1329 'Edit affiliation weights').click()1330 self.browser.find_element_by_name('weight_1').send_keys('40')1331 self.browser.find_element_by_name('weight_2').send_keys('40')1332 self._save_screenshot(self.admin_image_root, 'affiliation_weights')1333 self.browser.find_element_by_name('submit').click()1334 self.assertIn('The affiliation weights have been updated.',1335 self.browser.page_source)1336 # Enter times by weather band.1337 self.browser.find_element_by_link_text(1338 'Edit time available').click()1339 self.browser.find_element_by_name('available_1').send_keys('150')1340 self.browser.find_element_by_name('available_2').send_keys('250')1341 self.browser.find_element_by_name('available_3').send_keys('250')1342 self.browser.find_element_by_name('available_4').send_keys('200')1343 self.browser.find_element_by_name('available_5').send_keys('150')1344 self._save_screenshot(self.admin_image_root, 'time_available')1345 self.browser.find_element_by_name('submit').click()1346 self.assertIn('The time available has been saved.',1347 self.browser.page_source)1348 # Advance to the final review phase.1349 self.browser.find_element_by_link_text(1350 'Advance to final review phase').click()1351 self._save_screenshot(1352 self.admin_image_root, 'review_final', ['roles_closing_list'])1353 self.browser.find_element_by_name('submit_confirm').click()1354 self.assertIn('1 proposal advanced to the final review state',1355 self.browser.page_source)1356 # Look at the tabulation page and enter a decision.1357 self.browser.find_element_by_link_text(1358 'View detailed tabulation').click()1359 decision_link = self.browser.find_element_by_id('decision_1_link')1360 self._save_screenshot(self.admin_image_root, 'review_tabulation',1361 [decision_link])1362 decision_link.click()1363 Select(1364 self.browser.find_element_by_name('decision_accept')1365 ).select_by_visible_text('Accept proposal')1366 time_field = self.browser.find_element_by_name('time_new_1')1367 time_field.clear()1368 time_field.send_keys('2')1369 time_field = self.browser.find_element_by_name('time_new_2')1370 time_field.clear()1371 time_field.send_keys('6')1372 self._save_screenshot(self.admin_image_root, 'decision_edit')1373 self.browser.find_element_by_name('submit').click()1374 self.assertRegex(1375 self.browser.page_source,1376 'The decision for proposal [A-Z0-9]+ has been saved\.')1377 self._save_screenshot(self.admin_image_root,1378 'review_tabulation_updated')1379 # Look at the reviewer statistics page1380 self.browser.get(review_process_url)1381 self.browser.find_element_by_link_text(1382 'View review statistics').click()1383 self._save_screenshot(self.admin_image_root,1384 'review_statistics')1385 # Look at the allocation details page1386 self.browser.get(review_process_url)1387 self.browser.find_element_by_link_text(1388 'View allocation details').click()1389 self._save_screenshot(self.admin_image_root,1390 'allocation_details')1391 # View reviews page.1392 self.browser.get(review_process_url)1393 self.browser.find_element_by_link_text('Reviews').click()1394 self._save_screenshot(self.admin_image_root, 'proposal_reviews',1395 ['extra_review_links'])1396 # Enter feedback text.1397 self.browser.find_element_by_link_text('Add feedback').click()1398 self.browser.find_element_by_name('text').send_keys(1399 'This is an example feedback comment.')1400 self.browser.find_element_by_name('done').click()1401 self.browser.find_element_by_name('submit').click()1402 self.assertIn(1403 'The review has been saved and marked as done.',1404 self.browser.page_source)1405 # Check that the feedback approval page works.1406 self.browser.get(review_process_url)1407 self.browser.find_element_by_link_text(1408 'Approve feedback reports').click()1409 self.browser.find_element_by_xpath('//input[@type="checkbox"]').click()1410 self._save_screenshot(self.admin_image_root, 'approve_feedback')1411 self.browser.find_element_by_name('submit').click()1412 self.assertIn('The feedback approval status has been updated.',1413 self.browser.page_source)1414 def administer_site(self):1415 self.browser.get(self.base_url)1416 self.browser.find_element_by_link_text('Site administration').click()1417 admin_menu_url = self.browser.current_url1418 self._save_screenshot(self.admin_image_root, 'site_admin_menu')1419 self.browser.find_element_by_link_text('Email messages').click()1420 self._save_screenshot(self.admin_image_root, 'message_list')1421 self.browser.find_element_by_partial_link_text('submitted').click()1422 thread_link = self.browser.find_element_by_id('message_thread_link')1423 self._save_screenshot(self.admin_image_root, 'message_view',1424 [thread_link])1425 thread_link.click()1426 self.assertIn('<h1>Message thread:', self.browser.page_source)1427 self._save_screenshot(self.admin_image_root, 'message_thread')1428 # Move a message into the "error" state so that we can test the1429 # reset control.1430 messages = self.db.search_message(1431 state=MessageState.UNSENT, oldest_first=True)1432 self.assertTrue(messages)1433 self.db.update_message(1434 message_id=first_value(messages).id,1435 state_prev=MessageState.UNSENT, state=MessageState.ERROR,1436 state_is_system=True)1437 self.browser.find_element_by_link_text('Messages').click()1438 self.browser.find_element_by_xpath('//input[@type="checkbox"]').click()1439 self._save_screenshot(self.admin_image_root, 'message_reset',1440 ['message_state_control'])1441 self.browser.find_element_by_name('submit').click()1442 self.assertIn('The status for 1 message has been set to unsent.',1443 self.browser.page_source)1444 self.browser.get(admin_menu_url)1445 self.browser.find_element_by_link_text(1446 'Approve institution edits').click()1447 self._save_screenshot(self.admin_image_root, 'approve_inst_edit')1448 self.browser.get(admin_menu_url)1449 self.browser.find_element_by_link_text(1450 'View processing status').click()1451 self._save_screenshot(self.admin_image_root, 'processing_status')1452 self.browser.get(admin_menu_url)1453 self.browser.find_element_by_link_text('Unregistered users').click()1454 self._save_screenshot(self.admin_image_root, 'user_unregistered')1455 # View administrative links on a profile and institution pages.1456 self.browser.find_element_by_id('user_profile_link').click()1457 self._save_screenshot(self.admin_image_root, 'person_admin',1458 ['account_admin_links'])1459 self.browser.find_element_by_link_text('User account log').click()1460 self._save_screenshot(self.admin_image_root, 'user_log')1461 self.browser.back()1462 self.browser.find_element_by_link_text(1463 'Subsume duplicate profile').click()1464 Select(1465 self.browser.find_element_by_name('duplicate_id')1466 ).select_by_visible_text(1467 'Another Person, Test Institution, United States')1468 self._save_screenshot(self.admin_image_root, 'person_subsume')1469 self.browser.find_element_by_name('submit').click()1470 self._save_screenshot(self.admin_image_root, 'person_subsume_confirm')1471 self.browser.find_element_by_name('submit_cancel').click()1472 self.browser.find_element_by_partial_link_text(1473 'View this institution').click()1474 self._save_screenshot(self.admin_image_root, 'institution_links',1475 ['institution_admin_links'])1476 self.browser.find_element_by_link_text('View edit log').click()1477 self._save_screenshot(self.admin_image_root, 'institution_log')1478 self.browser.back()1479 self.browser.find_element_by_link_text(1480 'Subsume duplicate record').click()1481 Select(1482 self.browser.find_element_by_name('duplicate_id')1483 ).select_by_visible_text('Another Institution, United States')1484 self._save_screenshot(self.admin_image_root, 'institution_subsume')1485 self.browser.find_element_by_name('submit').click()1486 self._save_screenshot(self.admin_image_root,1487 'institution_subsume_confirm')1488 self.browser.find_element_by_name('submit_cancel').click()1489 # Test the site group system.1490 self.browser.get(admin_menu_url)1491 self.browser.find_element_by_link_text('Profile viewers').click()1492 self.browser.find_element_by_link_text('Add member').click()1493 self._save_screenshot(1494 self.admin_image_root, 'site_group_view_prof_add')1495 self.browser.find_element_by_name('name').send_keys(1496 'Site Group Member')1497 self.browser.find_element_by_name('email').send_keys(1498 'member@somewhere.edu')1499 self.browser.find_element_by_name('submit_invite').click()1500 self.assertIn(1501 'Site Group Member has been added to the site group.',1502 self.browser.page_source)1503 Select(1504 self.browser.find_element_by_name('institution_id')1505 ).select_by_visible_text(1506 'Test Institution, United States')1507 self.browser.find_element_by_name('submit_select').click()1508 self.assertIn(1509 'The institution has been selected.',1510 self.browser.page_source)1511 self.browser.get(self.browser.current_url)1512 self._save_screenshot(self.admin_image_root, 'site_group_view_prof')1513 self.browser.find_element_by_link_text('Edit members').click()1514 self._save_screenshot(1515 self.admin_image_root, 'site_group_view_prof_edit')1516 self.browser.find_element_by_name('submit').click()1517 self.assertIn(1518 'The site group membership has been saved.',1519 self.browser.page_source)1520 def view_user_directory(self):1521 self.browser.get(self.base_url + 'person')1522 self.browser.find_element_by_link_text('take admin').click()1523 Select(1524 self.browser.find_element_by_name('registered')1525 ).select_by_visible_text('Any status')1526 self.browser.find_element_by_name('submit').click()1527 self._save_screenshot(self.admin_image_root, 'person_list')1528 self.browser.find_element_by_link_text(1529 'Invited Member').click()1530 self._save_screenshot(1531 self.admin_image_root, 'person_unregistered',1532 ['account_admin_links'])1533 self.browser.find_element_by_link_text(1534 'Invite to register').click()1535 self._save_screenshot(self.admin_image_root, 'person_invite')1536 self.browser.find_element_by_name('submit_cancel').click()1537 def open_new_call(self, facility_code):1538 self.browser.get(self.base_url + facility_code)1539 self.browser.find_element_by_link_text('Administrative menu').click()1540 admin_menu_url = self.browser.current_url1541 # Create a new semester.1542 semester_name = self._create_semester('B')1543 # Create a call.1544 self.browser.get(admin_menu_url)1545 self._create_call('Rapid Turnaround', semester_name)1546 return semester_name1547 def view_proposal_feedback(self, facility_code, proposal_id):1548 self.browser.get(self.base_url +1549 '{}/proposal/{}'.format(facility_code, proposal_id))1550 feedback_link = self.browser.find_element_by_link_text('View feedback')1551 self._save_screenshot(self.user_image_root, 'proposal_reviewed',1552 [feedback_link])1553 feedback_link.click()1554 self.assertIn('<h2>Comments</h2>', self.browser.page_source)1555 self._save_screenshot(self.user_image_root, 'proposal_feedback')1556 def copy_proposal(1557 self, facility_code, semester_name, call_type_name=None,1558 screenshot_path=None):1559 self.browser.get(self.base_url + facility_code)1560 if call_type_name is None:1561 self.browser.find_element_by_link_text(semester_name).click()1562 else:1563 self.browser.find_element_by_link_text('Other calls for proposals').click()1564 self.browser.find_element_by_link_text(call_type_name).click()1565 queue_link = self.browser.find_element_by_partial_link_text(1566 'Create a proposal for the PI Science Queue')1567 queue_link.click()1568 Select(1569 self.browser.find_element_by_name('affiliation_id')1570 ).select_by_visible_text('China')1571 self._save_screenshot(screenshot_path, 'proposal_copy')1572 self.browser.find_element_by_name('submit_copy').click()1573 self.assertIn(1574 'Please wait while your proposal is copied.',1575 self.browser.page_source)1576 # Process the request and refresh now -- should be redirected to copy.1577 process_request_prop_copy(self.db, self.server.app)1578 self.browser.refresh()1579 self.assertIn(1580 'Proposal Copy Report',1581 self.browser.page_source)1582 self.assertNotIn(1583 'Error',1584 self.browser.page_source)1585 self.browser.find_element_by_id('callout_dismiss').click()1586 self._save_screenshot(1587 screenshot_path, 'proposal_copied')1588 self._submit_proposal()1589 def try_jcmt_itcs(self):1590 self.browser.get(self.base_url + 'jcmt/calculator/scuba2/time')1591 self._save_screenshot(self.user_image_root, 'calc_scuba2_input')1592 self.browser.get(self.base_url + 'jcmt/calculator/heterodyne/time')1593 self._save_screenshot(self.user_image_root, 'calc_jcmt_het_input')1594 def try_jcmt_tools(self):1595 self.browser.get(self.base_url + 'jcmt/tool/clash')1596 self.browser.find_element_by_name('x').send_keys('12:34:56')1597 self.browser.find_element_by_name('y').send_keys('7:08:09')1598 self.browser.find_element_by_name('submit_calc').click()1599 self.assertIn(1600 'No match was found for the following targets:',1601 self.browser.page_source)1602 self._save_screenshot(1603 self.user_image_root, 'target_clash_single',1604 ['perm_query_link', 'tool_upload_link'])1605 self.browser.get(self.base_url + 'jcmt/tool/avail')1606 self.browser.find_element_by_name('x').send_keys('12:34:56')1607 self.browser.find_element_by_name('y').send_keys('7:08:09')1608 self.browser.find_element_by_name('submit_calc').click()1609 self.assertIn(1610 '<h3>Availability by Date</h3>',1611 self.browser.page_source)1612 self._save_screenshot(1613 self.user_image_root, 'target_avail_single',1614 ['perm_query_link', 'tool_upload_link'])1615 def _save_screenshot(self, path, name, highlight=[]):1616 if path is None:1617 return1618 for highlight_element in highlight:1619 if not isinstance(highlight_element, string_type):1620 highlight_element = highlight_element.get_attribute('id')1621 self.browser.execute_script(1622 'document.getElementById("' + highlight_element +1623 '").classList.add("highlight_for_doc");')1624 path_small = os.path.join(path, name + '.png')1625 path_large = os.path.join(path, name + '_large.png')1626 self.browser.save_screenshot(path_large)1627 im = Image.open(path_large)1628 size = tuple(int(x / 2) for x in im.size)1629 im = im.resize(size, resample=Image.BICUBIC)...

Full Screen

Full Screen

basepage.py

Source:basepage.py Github

copy

Full Screen

1import datetime2import time3import unittest4from selenium import webdriver5from selenium.webdriver.support.wait import WebDriverWait6from selenium.webdriver.support import expected_conditions as EC7from selenium.webdriver.common.by import By8from selenium.webdriver.remote import webdriver9# from appium import webdriver10from appium.webdriver.common.touch_action import TouchAction1112from Common import logger, dir_config13import logging14import re151617class BasePage:18 def __init__(self, driver):19 self.driver = driver2021 def wait_eleVisible(self, locator, by=By.XPATH, model='model', wait=30, requence=0.5):22 # 等待元素可见 - 等待的时间 起始时间/结束时间23 try:24 start = datetime.datetime.now()25 WebDriverWait(self.driver, wait, requence).until(EC.visibility_of_element_located((by, locator)))26 end = datetime.datetime.now()27 wait_times = (end - start).seconds28 logging.info("等待元素可见:{0},起始时间:{1},等待时长:{2}".format(locator, start, wait_times))29 except:30 # 日志31 logging.exception("等待元素可见异常")32 # 截图 - 图放哪儿去?图的名字?33 self._save_screenShot(model)34 raise3536 # 等待元素存在37 def wait_elePrences(self, locator, by=By.XPATH, model='model', wait=30, requence=0.5):38 # 等待元素存在- 等待的时间 起始时间/结束时间39 try:40 start = datetime.datetime.now()41 WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located((by, locator)))42 end = datetime.datetime.now()43 wait_times = (end - start).seconds44 logging.info("等待元素存在:{0},起始时间:{1},等待时长:{2}".format(locator, start, wait_times))45 except:46 # 日志47 logging.exception("等待元素存在异常")48 # 截图 - 图放哪儿去?图的名字?49 self._save_screenShot(model)50 raise5152 # 等待元素存在53 def implicitly_wait(self, wait, model='model'):54 # 等待元素存在- 等待的时间 起始时间/结束时间55 try:56 return self.driver.implicitly_wait(wait)57 except:58 # 日志59 logging.exception("等待元素存在异常")60 # 截图 - 图放哪儿去?图的名字?61 self._save_screenShot(model)62 raise6364 def find_element(self, locator, by=By.XPATH, model='model'):65 # 查找元素66 logging.info("开始查找元素:{0}={1}".format(by, locator))67 try:68 return self.driver.find_element(by, locator)69 except:70 logging.exception("查找元素失败。")71 self._save_screenShot(model)72 raise7374 def find_element_by_id(self, locator, by=By.ID, model='model'):75 # 查找元素76 logging.info("开始查找元素:{0}={1}".format(by, locator))77 try:78 return self.driver.find_element(by, locator)79 except:80 logging.exception("查找元素失败。")81 self._save_screenShot(model)82 raise8384 def find_element_wait_and_focus(self, locator, wait_ele, by=By.XPATH, model='model', wait=30,85 requence=0.5, index=None):86 # 查找元素87 logging.info("开始查找元素:{0}={1}".format(by, locator))88 # 等待元素89 if wait_ele == 'visibility':90 self.wait_eleVisible(locator, by, model, wait,requence)91 else:92 self.wait_elePrences(locator, by, model, wait,requence)9394 # 滚到元素到可视区域95 self.focus(locator, by, model,index)9697 try:98 return self.driver.find_element(by, locator)99 except:100 logging.exception("查找元素失败。")101 self._save_screenShot(model)102 raise103104 def find_element_wait_and_focus_id(self, locator, wait_ele, by=By.ID, model='model', wait=30, requence=0.5, index=None):105 # 查找元素106 logging.info("开始查找元素:{0}={1}".format(by, locator))107 # 等待元素108 if wait_ele == 'visibility':109 self.wait_eleVisible(locator, by, model, wait, requence)110 else:111 self.wait_elePrences(locator, by, model, wait, requence)112113 # 滚到元素到可视区域114 self.focus_id(locator, by, model,index)115116 try:117 return self.driver.find_element(by, locator)118 except:119 logging.exception("查找元素失败。")120 self._save_screenShot(model)121 raise122123124 # 查的多个元素125 def find_elements(self, locator, by=By.XPATH, model='model'):126 # 查找元素127 logging.info("开始查找符合表达式的所有元素:{0}={1}".format(by, locator))128 try:129 return self.driver.find_elements(by, locator)130 except:131 logging.exception("查找元素失败。")132 self._save_screenShot(model)133 raise134135 # 元素的点击操作。136 def click_element(self, locator, wait_ele='visibility', by=By.XPATH, model='model', wait=30, requence=0.5,137 index=None):138 '''139 :param locator:元素定位的表达式140 :param by:元素定位的类型141 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。142 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。143 index=None表示查找一个元素。144 index=-1 表示查找多个元素,并在多个元素中随机选一个;145 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。146 :return:无147 '''148 logging.info("执行点击操作!")149 ele = self.find_element_wait_and_focus(locator, wait_ele, by, model, wait,150 requence, index)151 try:152 ele.click()153 except:154 logging.exception("{0}下的元素执行点击操作失败。".format(model))155 self._save_screenShot(model)156 raise157158 # 元素的输入操作159160 def input_text(self, value, locator, by=By.XPATH, model='model',wait=30,requence=0.5,161 wait_ele='visibility',index=None):162 """163 :param value: 要输入的文本值164 :param locator:元素定位的表达式165 :param by:元素定位的类型166 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。167 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。168 index=None表示查找一个元素。169 index=-1 表示查找多个元素,并在多个元素中随机选一个;170 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。171 :return:无172 """173 # ele = self._get_element(locator, by, model, index)174 ele = self.find_element_wait_and_focus(locator, wait_ele, by, model, wait,175 requence, index)176 try:177 ele.clear()178 ele.send_keys(value)179 except:180 logging.exception("{0}下的元素执行输入操作失败。".format(model))181 self._save_screenShot(model)182 raise183184 # id元素的输入操作185 def id_input_text(self, value, locator, by=By.ID, model='model', wait=30, requence=0.5,186 wait_ele='visibility', index=None):187 """188 :param value: 要输入的文本值189 :param locator:元素定位的表达式190 :param by:元素定位的类型191 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。192 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。193 index=None表示查找一个元素。194 index=-1 表示查找多个元素,并在多个元素中随机选一个;195 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。196 :return:无197 """198 # ele = self._get_element(locator, by, model, index)199 ele = self.find_element_by_id(locator, by)200 try:201 ele.clear()202 ele.send_keys(value)203 except:204 logging.exception("{0}下的元素执行输入操作失败。".format(model))205 self._save_screenShot(model)206 raise207208 # xpath元素的输入操作209 def xpath_input_text(self, value, locator, by=By.XPATH, model='model', wait=30, requence=0.5,210 wait_ele='visibility', index=None):211 """212 :param value: 要输入的文本值213 :param locator:元素定位的表达式214 :param by:元素定位的类型215 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。216 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。217 index=None表示查找一个元素。218 index=-1 表示查找多个元素,并在多个元素中随机选一个;219 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。220 :return:无221 """222 # ele = self._get_element(locator, by, model, index)223 ele = self.find_element(locator, by)224 try:225 ele.clear()226 ele.send_keys(value)227 except:228 logging.exception("{0}下的元素执行输入操作失败。".format(model))229 self._save_screenShot(model)230 raise231232 def id_click_element(self, locator, wait_ele='visibility', by=By.ID, model='model', wait=30, requence=0.5,233 index=None):234 '''235 :param locator:元素定位的表达式236 :param by:元素定位的类型237 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。238 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。239 index=None表示查找一个元素。240 index=-1 表示查找多个元素,并在多个元素中随机选一个;241 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。242 :return:无243 '''244 logging.info("执行点击操作!")245 ele = self.find_element_by_id(locator, by)246 try:247 ele.click()248 except:249 logging.exception("{0}下的元素执行点击操作失败。".format(model))250 self._save_screenShot(model)251 raise252253 # 获取元素的属性值。254255 def get_element_attribube(self, attr_name, locator, by=By.XPATH,model='model',wait=30,requence=0.5,256 wait_ele='visibility',index=None):257 """258 :param attr_name: 元素的属性名称259 :param locator:元素定位的表达式260 :param by:元素定位的类型261 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。262 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。263 index=None表示查找一个元素。264 index=-1 表示查找多个元素,并在多个元素中随机选一个;265 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。266 :return:元素的属性值。267 """268 logging.info("{0}:获取元素{1}={2} 的属性值:{3}。".format(model, by, locator, attr_name))269 ele = self.find_element_wait_and_focus(locator, wait_ele, by, model, wait,270 requence, index)271 try:272 return ele.get_attribute(attr_name)273 except:274 logging.exception("获取元素的属性:{0} 失败。".format(attr_name))275 self._save_screenShot(model)276 raise277278 # 获取元素的文本内容279280 def get_text(self, locator, by=By.XPATH, model='model',wait=30,requence=0.5,281 wait_ele='visibility',index=None):282 """283 :param locator:元素定位的表达式284 :param by:元素定位的类型285 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。286 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。287 index=None表示查找一个元素。288 index=-1 表示查找多个元素,并在多个元素中随机选一个;289 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。290 :return:元素的文本内容。291 """292 logging.info("{0}:获取元素{1}={2} 的文本内容。".format(model, by, locator))293 ele = self.find_element_wait_and_focus(locator, wait_ele, by, model, wait,294 requence, index)295 try:296 return ele.text297 except:298 logging.exception("获取元素文本失败。")299 self._save_screenShot(model)300 raise301302 def id_get_text(self, locator, by=By.ID, model='model',wait=30,requence=0.5,303 wait_ele='visibility',index=None):304 """305 :param locator:元素定位的表达式306 :param by:元素定位的类型307 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。308 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。309 index=None表示查找一个元素。310 index=-1 表示查找多个元素,并在多个元素中随机选一个;311 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。312 :return:元素的文本内容。313 """314 logging.info("{0}:获取元素{1}={2} 的文本内容。".format(model, by, locator))315 ele = self.find_element_wait_and_focus_id(locator, wait_ele, by, model, wait, requence, index)316317 try:318 return ele.text319 except:320 logging.exception("获取元素文本失败。")321 self._save_screenShot(model)322 raise323324 def xpath_get_text(self, locator, by=By.XPATH):325 logging.info("{0}:获取元素{1}={2} 的文本内容。".format(model, by, locator))326 ele = self.find_element(by, locator)327 try:328 return ele.text()329 except:330 logging.exception("获取元素文本失败。")331 self._save_screenShot(model)332 raise333334 # 元素滚动操作335 def focus(self, locator, by=By.XPATH, model='model', index=None):336 """337 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。338 index=None表示查找一个元素。339 index=-1 表示查找多个元素,并在多个元素中随机选一个;340 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。341 :return: 无342 """343 logging.info("{0}:滚动元素{1}={2} 到可见区域".format(model, by, locator))344 ele = self._get_element(locator, by, model, index)345 try:346 self.driver.execute_script("arguments[0].scrollIntoView();", ele)347 except:348 logging.exception("滚动失败")349 self._save_screenShot(model)350 raise351352 # 元素滚动操作353 def focus_id(self, locator, by=By.ID, model='model', index=None):354 """355 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。356 index=None表示查找一个元素。357 index=-1 表示查找多个元素,并在多个元素中随机选一个;358 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。359 :return: 无360 """361 logging.info("{0}:滚动元素{1}={2} 到可见区域".format(model, by, locator))362 ele = self._get_element(locator, by, model, index)363 try:364 self.driver.execute_script("arguments[0].scrollIntoView();", ele)365 except:366 logging.exception("滚动失败")367 self._save_screenShot(model)368 raise369370 # 截图函数371 def _save_screenShot(self, model_name="model"):372 # 根据功能和时间点生成截图373 # 文件格式 :功能名称_年月日-时分秒.png374 try:375 file_path = dir_config.screenshot_dir + "/{0}_{1}.png".format(model_name,376 time.strftime("%Y-%m-%d-%H-%M-%S",377 time.localtime()))378 # 截图文件存放在 Screenshot目录下379 # driver方法:self.driver.save_screenshot()380 self.driver.save_screenshot(file_path)381 logging.info("截图成功,路径为:{0}".format(file_path))382 except:383 logging.exception('截图失败')384 raise385386 # 确定要操作的元素 - 查找多个和查找单个。确定元素操作对象。387 def _get_element(self, locator, by, model="model", index=None):388 # index为None表示查找单个元素。不为None表示查找多个元素,并在多个元素中选一个。389 if index is not None:390 # 在查找到多个元素的基础之上,选择其中的一个。391 return self._select_ele_from_elements(locator, by, model, index)392 else:393 return self.find_element(locator, by, model)394395 # 在查找到的多个元素中,选择一个元素。396 def _select_ele_from_elements(self, locator, by, model="model", index=-1):397 """398 :param index: -1 表示随机选;0及0以上的值表示按下标选值。399 :return:返回选中的元素400 """401 import random402 eles = self.find_elements(locator, by, model)403 if index == -1 or index < 0:404 pos = random.randint(0, len(eles) - 1)405 return eles[pos]406 else:407 return eles[index]408409 # 元素的点击操作。410 def click_element2(self, locator,wait_ele='visibility', by=By.XPATH, model='model', wait=30, requence=0.5,index=None):411 '''412 :param locator:元素定位的表达式413 :param by:元素定位的类型414 :param model:模块或者用例名称。主要用在截图文件命名中,方便查找和定位。415 :param index: 是否要在多个元素中选择一个元素来操作。应用于查找多个元素的基础。416 index=None表示查找一个元素。417 index=-1 表示查找多个元素,并在多个元素中随机选一个;418 index > -1 表示查找多个元素,并且根据index的值取对应下标的元素。419 :return:无420 '''421 logging.info("执行点击操作!")422 ele = self.find_element_wait_and_focus(locator, wait_ele, by, model, wait,423 requence, index)424 try:425 ele.click()426 except:427 logging.exception("{0}下的元素执行点击操作失败。".format(model))428 self._save_screenShot(model)429 raise430431 # 纯文本定位/toast,返回toast文本内容432 def get_toast_text(self, locator, by=By.XPATH, wait=5, requence=0.01, model='model'):433 """434 ########################################435 描述:获取Toast的文本信息436 参数:text需要检查的提示信息 time检查总时间 poll_frequency检查时间间隔437 返回值:返回与之匹配到的toast信息438 异常描述:none439 ########################################440 """441 logging.info("查找toast")442443 message = (by, locator)444 toast_element = WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located(message))445446 try:447 logging.exception("找到toast信息")448 return toast_element.text449450 except:451 logging.exception("未查找到toast信息")452 self._save_screenShot(model)453 raise454455 def find_toast(self, message):456 u'''获取toast信息文本并验证'''457 message1 = "//*[@text=\'{}\']".format(message)458 element = WebDriverWait(self.driver, 5, 0.01).until(459 EC.presence_of_element_located((By.XPATH, message1)))460 return element.text461462 # 纯文本定位/toast463 def text_element(self, locator, by=By.XPATH, wait=5, requence=0.01, model='model'):464 """465 ########################################466 描述:获取Toast的文本信息467 参数:text需要检查的提示信息 time检查总时间 poll_frequency检查时间间隔468 返回值:返回与之匹配到的toast信息469 异常描述:none470 ########################################471 """472 logging.info("查找toast")473474 message = (by, locator)475 toast_element = WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located(message))476477 try:478 return toast_element479480 except:481 logging.exception("未查找到toast信息")482 self._save_screenShot(model)483 raise484485 def swipeLeft(self, n):486 """487 向左滑动488 """489 size = self.driver.get_window_size()490 width = size['width']491 height = size['height']492 time.sleep(2)493494 x1 = width * 0.8495 x2 = width * 0.2496 y1 = height * 0.5497498 for i in range(n):499 self.driver.swipe(x1, y1, x2, y1)500501 def swipeRight(self, n):502 """503 向右滑动504 """505 size = self.driver.get_window_size()506 width = size['width']507 height = size['height']508509 x1 = width * 0.2510 x2 = width * 0.8511 y1 = height * 0.5512513 for i in range(n):514 self.driver.swipe(x1, y1, x2, y1)515516 def swipeUp(self, n):517 """518 向上滑动519 """520 size = self.driver.get_window_size()521 width = size['width']522 height = size['height']523524 x1 = width * 0.5525 y1 = width * 0.9526 y2 = height * 0.25527528 for i in range(n):529 self.driver.swipe(x1, y1, x1, y2)530531 def swipeDown(self, n):532 """533 向下滑动534 """535 size = self.driver.get_window_size()536 width = size['width']537 height = size['height']538539 x1 = width * 0.5540 y1 = width * 0.25541 y2 = height * 0.9542543 for i in range(n):544 self.driver.swipe(x1, y1, x1, y2)545546 # 具体文本不确定的时候,查找toast547 def find_toast(self, value, model='model'):548 # 查找toast549 logging.info("开始查找元素:{0}={1}")550 toast_msg = value551 message = '//*[@text=\'{}\']'.format(toast_msg)552 self.wait_eleVisible(message)553 toast_text = self.find_element(message)554 try:555 return toast_text.text556 except:557 logging.exception("查找元素失败。")558 self._save_screenShot(model)559 raise560561 # 手机-长按562 def long_press(self, locator):563 action = TouchAction(self.driver)564 el = self.find_elements(locator)[0]565 action.long_press(el=el, duration=2000).wait(2000).perform()566567 # 坐标点击(用于处理蒙层)568 def touch_tap(self, x, y): # 点击坐标 ,x1,x2,y1,y2569 '''method570 explain: 点击坐标571 parameter572 explain:【x, y】坐标值,【duration】:给的值决定了点击的速度573 Usage:574 device.touch_coordinate(277, 431) # 277.431为点击某个元素的x与y值575 '''576577 TouchAction(self.driver).press(x=x, y=y).release().perform()578579 # 判断元素是否存在于当前页面,备注:只能识别by_id580 def find_item(self, el):581 logging.info("开始查找元素:{0}={1}")582 source = self.driver.page_source583 if el in source:584 return True585 else:586 return False587588 def back(self):589 self.driver.press_keycode(4)590591 # 判断元素是否可见592 def find_element_page(self, locator, by=By.XPATH, wait=30, requence=0.05, model='model'):593 """594 ########################################595 描述:获取Toast的文本信息596 参数:text需要检查的提示信息 time检查总时间 poll_frequency检查时间间隔597 返回值:返回与之匹配到的toast信息598 异常描述:none599 ########################################600 """601 logging.info("查找元素")602603 message = (by, locator)604605 try:606 WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located(message))607 return True608609 except:610 logging.exception("未查找到元素")611 self._save_screenShot(model)612 return False613614 # 判断元素是否可见615 def find_element_pages(self, locator, by=By.XPATH, wait=30, requence=0.05, model='model'):616 """617 ########################################618 描述:获取Toast的文本信息619 参数:text需要检查的提示信息 time检查总时间 poll_frequency检查时间间隔620 返回值:返回与之匹配到的toast信息621 异常描述:none622 ########################################623 """624625 message = (by, locator)626627 try:628 WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_locateds(message))629 return True630631 except:632 logging.exception("未查找到元素")633 self._save_screenShot(model) ...

Full Screen

Full Screen

__init__.py

Source:__init__.py Github

copy

Full Screen

...64 # self.last_screenshot65 cv_last_img = imutils.from_pillow(self.last_screenshot)66 cv_last_img = imutils.mark_point(cv_last_img, x, y)67 screen = imutils.to_pillow(cv_last_img)68 screen_before = self._save_screenshot(screen=screen, name_prefix='click-before')69 # FIXME: maybe need sleep for a while70 screen_after = self._save_screenshot(name_prefix='click-after')71 self.add_step('click',72 screen_before=screen_before,73 screen_after=screen_after,74 position={'x': x, 'y': y})75 def add_step(self, action, **kwargs):76 kwargs['success'] = kwargs.pop('success', True)77 kwargs['description'] = kwargs.get('description') or kwargs.get('desc')78 kwargs['time'] = round(kwargs.pop('time', time.time()-self.start_time), 1)79 kwargs['action'] = action80 self.steps.append(kwargs)81 def patch_uiautomator(self):82 """83 Record steps of uiautomator84 """85 import uiautomator86 uiautomator.add_listener('atx-report', self._uia_listener)87 def patch_wda(self):88 """89 Record steps of WebDriverAgent90 """91 import wda92 def _click(that):93 rawx, rawy = that.bounds.center94 x, y = self.d.scale*rawx, self.d.scale*rawy95 screen_before = self._save_screenshot()96 orig_click = pt.get_original(wda.Selector, 'click')97 screen_after = self._save_screenshot()98 self.add_step('click',99 screen_before=screen_before,100 screen_after=screen_after,101 position={'x': x, 'y': y})102 return orig_click(that)103 pt.patch_item(wda.Selector, 'click', _click)104 def start_record(self):105 self.start_time = time.time()106 w, h = self.d.display107 if self.d.rotation in (1, 3): # for horizontal108 w, h = h, w109 self.result = dict(device=dict(110 display=dict(width=w, height=h),111 serial=getattr(self.d, 'serial', ''),112 start_time=time.strftime("%Y-%m-%d %H:%M:%S"),113 start_timestamp=time.time(),114 ), steps=self.steps)115 self.d.add_listener(self._listener, consts.EVENT_ALL) # ^ consts.EVENT_SCREENSHOT)116 self.__closed = False117 atexit.register(self.close)118 def close(self):119 if self.__closed:120 return121 save_dir = self.save_dir122 data = json.dumps(self.result)123 tmpl_path = os.path.join(__dir__, 'index.tmpl.html')124 save_path = os.path.join(save_dir, 'index.html')125 json_path = os.path.join(save_dir, 'result.json')126 with codecs.open(tmpl_path, 'rb', 'utf-8') as f:127 html_content = f.read().replace('$$data$$', data)128 with open(json_path, 'wb') as f:129 f.write(json.dumps(self.result, indent=4).encode('utf-8'))130 with open(save_path, 'wb') as f:131 f.write(html_content.encode('utf-8'))132 self.__gif.close()133 self.__closed = True134 def info(self, text, screenshot=None):135 """136 Args:137 - text(str): description138 - screenshot: Bool or PIL.Image object139 """140 step = {141 'time': '%.1f' % (time.time()-self.start_time,),142 'action': 'info',143 'description': text,144 'success': True,145 } 146 if screenshot:147 step['screenshot'] = self._take_screenshot(screenshot, name_prefix='info')148 self.steps.append(step)149 def error(self, text, screenshot=None):150 """151 Args:152 - text(str): description153 - screenshot: Bool or PIL.Image object154 """155 step = {156 'time': '%.1f' % (time.time()-self.start_time,),157 'action': 'error',158 'description': text,159 'success': False,160 } 161 if screenshot:162 step['screenshot'] = self._take_screenshot(screenshot, name_prefix='error')163 self.steps.append(step)164 def _save_screenshot(self, screen=None, name=None, name_prefix='screen'):165 if screen is None:166 screen = self.d.screenshot()167 if name is None:168 name = 'images/%s_%d.jpg' % (name_prefix, time.time()*1000)169 relpath = os.path.join(self.save_dir, name)170 if hasattr(screen, 'convert'): # pillow image171 png = screen.convert("RGBA")172 bg = Image.new("RGB", png.size, (255, 255, 255))173 bg.paste(png, mask=png.split()[3]) # 3 is alpha channel174 bg.save(relpath, "JPEG", quality=80)175 self._add_to_gif(screen)176 else: # pattern177 screen.save(relpath)178 return name179 def _add_to_gif(self, image):180 half = 0.5181 out = image.resize([int(half*s) for s in image.size])182 cvimg = imutils.from_pillow(out)183 self.__gif.append_data(cvimg[:, :, ::-1])184 def _take_screenshot(self, screenshot=False, name_prefix='unknown'):185 """186 This is different from _save_screenshot.187 The return value maybe None or the screenshot path188 Args:189 screenshot: bool or PIL image190 """191 if isinstance(screenshot, bool):192 if not screenshot:193 return194 return self._save_screenshot(name_prefix=name_prefix)195 if isinstance(screenshot, Image.Image):196 return self._save_screenshot(screen=screenshot, name_prefix=name_prefix)197 raise TypeError("invalid type for func _take_screenshot: "+ type(screenshot))198 def _record_assert(self, is_success, text, screenshot=False, desc=None):199 step = {200 'time': '%.1f' % (time.time()-self.start_time,),201 'action': 'assert',202 'message': text,203 'description': desc,204 'success': is_success,205 'screenshot': self._take_screenshot(screenshot, name_prefix='assert'),206 }207 self.steps.append(step)208 def _add_assert(self, **kwargs):209 """210 if screenshot is None, only failed case will take screenshot211 """212 # convert screenshot to relative path from <None|True|False|PIL.Image>213 screenshot = kwargs.get('screenshot')214 is_success = kwargs.get('success')215 screenshot = (not is_success) if screenshot is None else screenshot216 kwargs['screenshot'] = self._take_screenshot(screenshot=screenshot, name_prefix='assert')217 action = kwargs.pop('action', 'assert')218 self.add_step(action, **kwargs)219 if not is_success:220 message = kwargs.get('message')221 frame, filename, line_number, function_name, lines, index = inspect.stack()[2]222 print('Assert [%s: %d] WARN: %s' % (filename, line_number, message))223 if not kwargs.get('safe', False):224 raise AssertionError(message)225 def assert_equal(self, v1, v2, **kwargs):#, desc=None, screenshot=False, safe=False):226 """ Check v1 is equals v2, and take screenshot if not equals227 Args:228 - desc (str): some description229 - safe (bool): will omit AssertionError if set to True230 - screenshot: can be type <None|True|False|PIL.Image>231 """232 is_success = v1 == v2233 if is_success:234 message = "assert equal success, %s == %s" %(v1, v2)235 else:236 message = '%s not equal %s' % (v1, v2)237 kwargs.update({238 'message': message,239 'success': is_success,240 })241 self._add_assert(**kwargs)242 def assert_image_exists(self, pattern, timeout=20.0, **kwargs):243 """244 Assert if image exists245 Args:246 - pattern: image filename # not support pattern for now247 - timeout (float): seconds248 - safe (bool): not raise assert error even throung failed.249 """250 pattern = self.d.pattern_open(pattern)251 match_kwargs = kwargs.copy()252 match_kwargs.pop('safe', None)253 match_kwargs.update({254 'timeout': timeout,255 'safe': True,256 })257 res = self.d.wait(pattern, **match_kwargs)258 is_success = res is not None259 message = 'assert image exists'260 if res:261 x, y = res.pos262 kwargs['position'] = {'x': x, 'y': y}263 message = 'image exists\npos %s\nconfidence=%.2f\nmethod=%s' % (res.pos, res.confidence, res.method)264 else:265 res = self.d.match(pattern)266 if res is None:267 message = 'Image not found'268 else:269 th = kwargs.get('threshold') or pattern.threshold or self.image_match_threshold270 message = 'Matched: %s\nPosition: %s\nConfidence: %.2f\nThreshold: %.2f' % (271 res.matched, res.pos, res.confidence, th)272 kwargs['target'] = self._save_screenshot(pattern, name_prefix='target')273 kwargs['screenshot'] = self.last_screenshot274 kwargs.update({275 'action': 'assert_image_exists',276 'message': message,277 'success': is_success,278 })279 self._add_assert(**kwargs)280 def assert_ui_exists(self, ui, **kwargs):281 """ For Android & IOS282 Args:283 - ui: need have property "exists"284 - desc (str): description285 - safe (bool): will omit AssertionError if set to True286 - screenshot: can be type <None|True|False|PIL.Image>287 - platform (str, default:android): android | ios288 """289 is_success = ui.exists290 if is_success:291 if kwargs.get('screenshot') is not None:292 if self.d.platform == 'android':293 bounds = ui.info['bounds'] # For android only.294 kwargs['position'] = {295 'x': (bounds['left']+bounds['right'])//2,296 'y': (bounds['top']+bounds['bottom'])//2,297 }298 elif self.d.platform == 'ios':299 bounds = ui.bounds # For iOS only.300 kwargs['position'] = {301 'x': self.d.scale*(bounds.x+bounds.width//2),302 'y': self.d.scale*(bounds.y+bounds.height//2),303 }304 message = 'UI exists'305 else:306 message = 'UI not exists'307 kwargs.update({308 'message': message,309 'success': is_success,310 })311 self._add_assert(**kwargs)312 def _listener(self, evt):313 d = self.d314 # keep screenshot for every call315 if not evt.is_before and evt.flag == consts.EVENT_SCREENSHOT:316 self.__last_screenshot = evt.retval317 if evt.depth > 1: # base depth is 1318 return319 if evt.is_before: # call before function320 if evt.flag == consts.EVENT_CLICK:321 self.__last_screenshot = d.screenshot() # Maybe no need to set value here.322 (x, y) = evt.args323 cv_img = imutils.from_pillow(self.last_screenshot)324 cv_img = imutils.mark_point(cv_img, x, y)325 self.__last_screenshot = imutils.to_pillow(cv_img)326 self._add_to_gif(self.last_screenshot)327 return328 if evt.flag == consts.EVENT_CLICK:329 screen_before = self._save_screenshot(self.last_screenshot, name_prefix='before')330 screen_after = self._save_screenshot(name_prefix='after')331 (x, y) = evt.args332 self.add_step('click',333 screen_before=screen_before,334 screen_after=screen_after,335 position={'x': x, 'y': y})336 elif evt.flag == consts.EVENT_CLICK_IMAGE:337 kwargs = {338 'success': evt.traceback is None,339 'traceback': None if evt.traceback is None else evt.traceback.stack,340 'description': evt.kwargs.get('desc'),341 }342 # do not record if image not found and no trackback343 if evt.retval is None and evt.traceback is None:344 return345 346 # save before click image347 kwargs['screen_before'] = self._save_screenshot(self.last_screenshot, name_prefix='before')348 if evt.traceback is None or not isinstance(evt.traceback.exception, IOError):349 pattern = d.pattern_open(evt.args[0])350 kwargs['target'] = self._save_screenshot(pattern, name_prefix='target')351 if evt.traceback is None:352 # update image to add a click mark353 (x, y) = evt.retval.pos354 cv_img = imutils.from_pillow(self.last_screenshot)355 cv_img = imutils.mark_point(cv_img, x, y)356 self.__last_screenshot = imutils.to_pillow(cv_img)357 kwargs['screen_before'] = self._save_screenshot(self.last_screenshot, name=kwargs['screen_before'])358 kwargs['screen_after'] = self._save_screenshot(name_prefix='after')359 kwargs['confidence'] = evt.retval.confidence360 kwargs['position'] = {'x': x, 'y': y}361 362 self.add_step('click_image', **kwargs)363 # elif evt.flag == consts.EVENT_ASSERT_EXISTS: # this is image, not tested364 # pattern = d.pattern_open(evt.args[0])365 # target = 'images/target_%.2f.jpg' % time.time()366 # self._save_screenshot(pattern, name=target)367 # kwargs = {368 # 'target': target,369 # 'description': evt.kwargs.get('desc'),370 # 'screen': self._save_screenshot(name='images/screen_%.2f.jpg' % time.time()),371 # 'traceback': None if evt.traceback is None else evt.traceback.stack,372 # 'success': evt.traceback is None,373 # }374 # if evt.traceback is None:375 # kwargs['confidence'] = evt.retval.confidence376 # (x, y) = evt.retval.pos377 # kwargs['position'] = {'x': x, 'y': y}378 # self.add_step('assert_exists', **kwargs)379def listen(d, save_dir='report'):380 ''' Depreciated '''381 warnings.warn(382 "Using report.listen is deprecated, use report.Report(d, save_dir) instead.", 383 ExtDeprecationWarning, stacklevel=2384 )...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run ATX automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful