functional_helpers.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #! /usr/bin/env python3
  2. #
  3. # BitBake Toaster functional tests implementation
  4. #
  5. # Copyright (C) 2017 Intel Corporation
  6. #
  7. # SPDX-License-Identifier: GPL-2.0-only
  8. #
  9. import os
  10. import logging
  11. import subprocess
  12. import signal
  13. import time
  14. import re
  15. from tests.browser.selenium_helpers_base import SeleniumTestCaseBase
  16. from tests.builds.buildtest import load_build_environment
  17. logger = logging.getLogger("toaster")
  18. class SeleniumFunctionalTestCase(SeleniumTestCaseBase):
  19. wait_toaster_time = 5
  20. @classmethod
  21. def setUpClass(cls):
  22. # So that the buildinfo helper uses the test database'
  23. if os.environ.get('DJANGO_SETTINGS_MODULE', '') != \
  24. 'toastermain.settings_test':
  25. raise RuntimeError("Please initialise django with the tests settings: " \
  26. "DJANGO_SETTINGS_MODULE='toastermain.settings_test'")
  27. load_build_environment()
  28. # start toaster
  29. cmd = "bash -c 'source toaster start'"
  30. p = subprocess.Popen(
  31. cmd,
  32. cwd=os.environ.get("BUILDDIR"),
  33. shell=True)
  34. if p.wait() != 0:
  35. raise RuntimeError("Can't initialize toaster")
  36. super(SeleniumFunctionalTestCase, cls).setUpClass()
  37. cls.live_server_url = 'http://localhost:8000/'
  38. @classmethod
  39. def tearDownClass(cls):
  40. super(SeleniumFunctionalTestCase, cls).tearDownClass()
  41. # XXX: source toaster stop gets blocked, to review why?
  42. # from now send SIGTERM by hand
  43. time.sleep(cls.wait_toaster_time)
  44. builddir = os.environ.get("BUILDDIR")
  45. with open(os.path.join(builddir, '.toastermain.pid'), 'r') as f:
  46. toastermain_pid = int(f.read())
  47. os.kill(toastermain_pid, signal.SIGTERM)
  48. with open(os.path.join(builddir, '.runbuilds.pid'), 'r') as f:
  49. runbuilds_pid = int(f.read())
  50. os.kill(runbuilds_pid, signal.SIGTERM)
  51. def get_URL(self):
  52. rc=self.get_page_source()
  53. project_url=re.search("(projectPageUrl\s:\s\")(.*)(\",)",rc)
  54. return project_url.group(2)
  55. def find_element_by_link_text_in_table(self, table_id, link_text):
  56. """
  57. Assume there're multiple suitable "find_element_by_link_text".
  58. In this circumstance we need to specify "table".
  59. """
  60. try:
  61. table_element = self.get_table_element(table_id)
  62. element = table_element.find_element_by_link_text(link_text)
  63. except self.NoSuchElementException:
  64. print('no element found')
  65. raise
  66. return element
  67. def get_table_element(self, table_id, *coordinate):
  68. if len(coordinate) == 0:
  69. #return whole-table element
  70. element_xpath = "//*[@id='" + table_id + "']"
  71. try:
  72. element = self.driver.find_element_by_xpath(element_xpath)
  73. except self.NoSuchElementException:
  74. raise
  75. return element
  76. row = coordinate[0]
  77. if len(coordinate) == 1:
  78. #return whole-row element
  79. element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]"
  80. try:
  81. element = self.driver.find_element_by_xpath(element_xpath)
  82. except self.NoSuchElementException:
  83. return False
  84. return element
  85. #now we are looking for an element with specified X and Y
  86. column = coordinate[1]
  87. element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]/td[" + str(column) + "]"
  88. try:
  89. element = self.driver.find_element_by_xpath(element_xpath)
  90. except self.NoSuchElementException:
  91. return False
  92. return element