Dynamically create new classes and add them to the test module when multiple browsers specs are provided (e.g. --selenium=firefox,chrome).
(cls, name, bases, attrs)
| 24 | headless = False |
| 25 | |
| 26 | def __new__(cls, name, bases, attrs): |
| 27 | """ |
| 28 | Dynamically create new classes and add them to the test module when |
| 29 | multiple browsers specs are provided (e.g. --selenium=firefox,chrome). |
| 30 | """ |
| 31 | test_class = super().__new__(cls, name, bases, attrs) |
| 32 | # If the test class is either browser-specific or a test base, return |
| 33 | # it. |
| 34 | if test_class.browser or not any( |
| 35 | name.startswith("test") and callable(value) for name, value in attrs.items() |
| 36 | ): |
| 37 | return test_class |
| 38 | elif test_class.browsers: |
| 39 | # Reuse the created test class to make it browser-specific. |
| 40 | # We can't rename it to include the browser name or create a |
| 41 | # subclass like we do with the remaining browsers as it would |
| 42 | # either duplicate tests or prevent pickling of its instances. |
| 43 | first_browser = test_class.browsers[0] |
| 44 | test_class.browser = first_browser |
| 45 | # Listen on an external interface if using a selenium hub. |
| 46 | host = test_class.host if not test_class.selenium_hub else "0.0.0.0" |
| 47 | test_class.host = host |
| 48 | test_class.external_host = cls.external_host |
| 49 | # Create subclasses for each of the remaining browsers and expose |
| 50 | # them through the test's module namespace. |
| 51 | module = sys.modules[test_class.__module__] |
| 52 | for browser in test_class.browsers[1:]: |
| 53 | browser_test_class = cls.__new__( |
| 54 | cls, |
| 55 | "%s%s" % (capfirst(browser), name), |
| 56 | (test_class,), |
| 57 | { |
| 58 | "browser": browser, |
| 59 | "host": host, |
| 60 | "external_host": cls.external_host, |
| 61 | "__module__": test_class.__module__, |
| 62 | }, |
| 63 | ) |
| 64 | setattr(module, browser_test_class.__name__, browser_test_class) |
| 65 | return test_class |
| 66 | # If no browsers were specified, skip this class (it'll still be |
| 67 | # discovered). |
| 68 | return unittest.skip("No browsers specified.")(test_class) |
| 69 | |
| 70 | @classmethod |
| 71 | def import_webdriver(cls, browser): |