Skip to content

Commit dfefefb

Browse files
committed
[tests] Updated tests and CI
1 parent 1765a8c commit dfefefb

File tree

5 files changed

+39
-44
lines changed

5 files changed

+39
-44
lines changed

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ jobs:
4646
with:
4747
ref: ${{ github.event.pull_request.head.sha }}
4848

49+
- name: Cache APT packages
50+
uses: actions/cache@v4
51+
with:
52+
path: /var/cache/apt/archives
53+
key: apt-${{ runner.os }}-${{ hashFiles('.github/workflows/ci.yml') }}
54+
restore-keys: |
55+
apt-${{ runner.os }}-
56+
57+
- name: Disable man page auto-update
58+
run: |
59+
echo 'set man-db/auto-update false' | sudo debconf-communicate >/dev/null
60+
sudo dpkg-reconfigure man-db
61+
4962
- name: Set up Python ${{ matrix.python-version }}
5063
uses: actions/setup-python@v5
5164
with:
@@ -68,6 +81,10 @@ jobs:
6881
pip install -UI --no-deps https://github.com/openwisp/openwisp-utils/tarball/browser-logs
6982
pip install ${{ matrix.django-version }}
7083
84+
- name: Start postgres and redis
85+
if: ${{ !cancelled() && steps.deps.conclusion == 'success' }}
86+
run: docker compose up -d postgres redis
87+
7188
- name: QA checks
7289
run: ./run-qa-checks
7390

@@ -84,6 +101,11 @@ jobs:
84101
coverage xml
85102
env:
86103
SELENIUM_HEADLESS: 1
104+
GECKO_LOG: 1
105+
106+
- name: Show gecko web driver log on failures
107+
if: ${{ failure() }}
108+
run: cat geckodriver.log
87109

88110
- name: Upload Coverage
89111
if: ${{ success() }}

openwisp_controller/config/tests/test_selenium.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@
1010
from selenium.webdriver.support.ui import Select, WebDriverWait
1111
from swapper import load_model
1212

13-
from openwisp_utils.test_selenium_mixins import SeleniumTestMixin
13+
from openwisp_utils.tests import SeleniumTestMixin
1414

15-
from ...tests.utils import DeviceAdminSeleniumTextMixin
1615
from .utils import CreateConfigTemplateMixin, TestWireguardVpnMixin
1716

1817
Device = load_model('config', 'Device')
1918

2019

2120
@tag('selenium_tests')
2221
class TestDeviceAdmin(
23-
DeviceAdminSeleniumTextMixin,
22+
SeleniumTestMixin,
2423
CreateConfigTemplateMixin,
2524
StaticLiveServerTestCase,
2625
):
@@ -97,6 +96,7 @@ def test_device_preview_keyboard_shortcuts(self):
9796
self.open(reverse('admin:config_device_changelist'))
9897
try:
9998
self.open(reverse('admin:config_device_change', args=[device.id]))
99+
self.hide_loading_overlay()
100100
except TimeoutException:
101101
self.fail('Device detail page did not load in time')
102102

@@ -140,6 +140,7 @@ def test_multiple_organization_templates(self):
140140
reverse('admin:config_device_change', args=[org1_device.id])
141141
+ '#config-group'
142142
)
143+
self.hide_loading_overlay()
143144
# org2 templates should not be visible
144145
self.wait_for_invisibility(
145146
By.XPATH, f'//*[@value="{org2_required_template.id}"]'
@@ -163,6 +164,7 @@ def test_change_config_backend(self):
163164
self.open(
164165
reverse('admin:config_device_change', args=[device.id]) + '#config-group'
165166
)
167+
self.hide_loading_overlay()
166168
self.find_element(by=By.XPATH, value=f'//*[@value="{template.id}"]')
167169
# Change config backed to
168170
config_backend_select = Select(
@@ -183,6 +185,7 @@ def test_template_context_variables(self):
183185
self.open(
184186
reverse('admin:config_device_change', args=[device.id]) + '#config-group'
185187
)
188+
self.hide_loading_overlay()
186189
try:
187190
WebDriverWait(self.web_driver, 2).until(
188191
EC.text_to_be_present_in_element_value(
@@ -216,6 +219,7 @@ def test_force_delete_device_with_deactivating_config(self):
216219

217220
self.login()
218221
self.open(reverse('admin:config_device_change', args=[device.id]))
222+
self.hide_loading_overlay()
219223
# The webpage has two "submit-row" sections, each containing a "Deactivate"
220224
# button. The first (top) "Deactivate" button is hidden, causing
221225
# `wait_for_visibility` to fail. To avoid this issue, we use
@@ -232,6 +236,7 @@ def test_force_delete_device_with_deactivating_config(self):
232236
self.assertEqual(config.is_deactivating(), True)
233237

234238
self.open(reverse('admin:config_device_change', args=[device.id]))
239+
self.hide_loading_overlay()
235240
# Use `presence` instead of `visibility` for `wait_for`,
236241
# as the same issue described above applies here.
237242
self.find_elements(
@@ -282,7 +287,7 @@ def test_force_delete_multiple_devices_with_deactivating_config(self):
282287

283288
@tag('selenium_tests')
284289
class TestDeviceAdminUnsavedChanges(
285-
DeviceAdminSeleniumTextMixin,
290+
SeleniumTestMixin,
286291
CreateConfigTemplateMixin,
287292
StaticLiveServerTestCase,
288293
):
@@ -297,9 +302,10 @@ def test_unsaved_changes(self):
297302
self.login()
298303
device = self._create_config(organization=self._get_org()).device
299304
path = reverse('admin:config_device_change', args=[device.id])
300-
self.open(path)
305+
301306
with self.subTest('Alert should not be displayed without any change'):
302307
self.open(path)
308+
self.hide_loading_overlay()
303309
try:
304310
WebDriverWait(self.web_driver, 1).until(EC.alert_is_present())
305311
except TimeoutException:

openwisp_controller/connection/tests/test_selenium.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from selenium.webdriver.common.by import By
55
from swapper import load_model
66

7-
from ...tests.utils import DeviceAdminSeleniumTextMixin
7+
from openwisp_utils.tests import SeleniumTestMixin
8+
89
from .utils import CreateConnectionsMixin
910

1011
Command = load_model('connection', 'Command')
@@ -13,7 +14,7 @@
1314
@tag('selenium_tests')
1415
class TestDeviceAdmin(
1516
CreateConnectionsMixin,
16-
DeviceAdminSeleniumTextMixin,
17+
SeleniumTestMixin,
1718
StaticLiveServerTestCase,
1819
):
1920
config_app_label = 'config'
@@ -36,12 +37,14 @@ def test_command_widget_on_device(self):
3637
self.login()
3738
path = reverse(f'admin:{self.config_app_label}_device_change', args=[device.id])
3839
self.open(path)
40+
self.hide_loading_overlay()
3941
# The "Send Command" widget is not visible on devices which do
4042
# not have a DeviceConnection object
4143
self.wait_for_invisibility(By.CSS_SELECTOR, 'ul.object-tools a#send-command')
4244
self._create_device_connection(device=device, credentials=creds)
4345
self.assertEqual(device.deviceconnection_set.count(), 1)
4446
self.open(path)
47+
self.hide_loading_overlay()
4548
# Send reboot command to the device
4649
self.find_element(
4750
by=By.CSS_SELECTOR, value='ul.object-tools a#send-command', timeout=5

openwisp_controller/tests/test_selenium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from openwisp_controller.connection.tests.utils import CreateConnectionsMixin
1515
from openwisp_controller.geo.tests.utils import TestGeoMixin
16-
from openwisp_utils.test_selenium_mixins import SeleniumTestMixin
16+
from openwisp_utils.tests import SeleniumTestMixin
1717

1818
Device = load_model('config', 'Device')
1919
DeviceConnection = load_model('connection', 'DeviceConnection')

openwisp_controller/tests/utils.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@
44
from django.db.utils import DEFAULT_DB_ALIAS
55
from django.test.testcases import _AssertNumQueriesContext
66
from django.urls import reverse
7-
from selenium.common.exceptions import TimeoutException, UnexpectedAlertPresentException
8-
from selenium.webdriver.common.by import By
9-
from selenium.webdriver.support import expected_conditions as EC
10-
from selenium.webdriver.support.ui import WebDriverWait
117

128
from openwisp_users.tests.utils import TestMultitenantAdminMixin
13-
from openwisp_utils.test_selenium_mixins import SeleniumTestMixin
149

1510
user_model = get_user_model()
1611

@@ -54,34 +49,3 @@ def assertNumQueries(self, num, func=None, *args, using=DEFAULT_DB_ALIAS, **kwar
5449

5550
with context:
5651
func(*args, **kwargs)
57-
58-
59-
class DeviceAdminSeleniumTextMixin(SeleniumTestMixin):
60-
def tearDown(self):
61-
super().tearDown()
62-
# Dismiss any unsaved changes alert to prevent it from blocking
63-
# navigation in subsequent tests. If left unresolved, this could
64-
# cause test failures by preventing the browser from loading new pages.
65-
# Ensuring a clean browser state before the next test runs.
66-
try:
67-
self.web_driver.refresh()
68-
except UnexpectedAlertPresentException:
69-
self.web_driver.switch_to_alert().accept()
70-
self.web_driver.switch_to_alert.accept()
71-
else:
72-
try:
73-
WebDriverWait(self.web_driver, 1).until(EC.alert_is_present())
74-
except TimeoutException:
75-
pass
76-
else:
77-
self.web_driver.switch_to_alert().accept()
78-
self.web_driver.refresh()
79-
self.wait_for_visibility(By.XPATH, '//*[@id="site-name"]')
80-
81-
def open(self, url, driver=None):
82-
super().open(url, driver)
83-
driver = driver or self.web_driver
84-
self._assert_loading_overlay_hidden()
85-
86-
def _assert_loading_overlay_hidden(self):
87-
self.wait_for_invisibility(By.CSS_SELECTOR, '#loading-overlay')

0 commit comments

Comments
 (0)