Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"config-0-config",
"config-0-context",
"devicelocation-0-geometry",
"geometry",
];
// ignore fields that have no name attribute, begin with "_" or "initial-"
if (
Expand Down
66 changes: 65 additions & 1 deletion openwisp_controller/geo/tests/test_selenium.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import tag
from django.urls.base import reverse
from django_loci.tests import TestAdminMixin
from django_loci.tests.base.test_selenium import BaseTestDeviceAdminSelenium
from selenium.webdriver.common.by import By
from swapper import load_model

from openwisp_users.tests.utils import TestOrganizationMixin
from openwisp_utils.tests import SeleniumTestMixin

from .utils import TestGeoMixin

Device = load_model('config', 'Device')
Location = load_model('geo', 'Location')
FloorPlan = load_model('geo', 'FloorPlan')
DeviceLocation = load_model('geo', 'DeviceLocation')


class TestDeviceAdminSelenium(
# these tests are for geo elements on device admin
@tag('selenium_tests')
class TestDeviceAdminGeoSelenium(
BaseTestDeviceAdminSelenium, TestOrganizationMixin, StaticLiveServerTestCase
):
app_label = 'geo'
Expand All @@ -27,6 +36,10 @@ class TestDeviceAdminSelenium(
def _get_prefix(cls):
return cls.inline_field_prefix

# set timeout to 5 seconds to allow enough time for presence of elements
def wait_for_presence(self, by, value, timeout=5, driver=None):
return super().wait_for_presence(by, value, timeout, driver)

def _fill_device_form(self):
org = self._get_org()
self.find_element(by=By.NAME, value='mac_address').send_keys(
Expand All @@ -46,3 +59,54 @@ def _fill_device_form(self):
)
self.find_element(by=By.CLASS_NAME, value='select2-results__option').click()
super()._fill_device_form()


@tag('selenium_tests')
class TestDeviceAdminUnsavedChangesGeoSelenium(
TestGeoMixin,
TestAdminMixin,
SeleniumTestMixin,
StaticLiveServerTestCase,
):
browser = 'chrome'
app_label = 'geo'

object_model = Device
location_model = Location
object_location_model = DeviceLocation
permission_model = Permission
user_model = get_user_model()

# for these tests we need readonly user with view permissions.
def setUp(self):
self.admin = self._create_readonly_admin(
username=self.admin_username,
password=self.admin_password,
models=[self.object_model, self.location_model, self.object_location_model],
)

def test_unsaved_changes_readonly(self):
self.login()
ol = self._create_object_location()
path = reverse('admin:config_device_change', args=[ol.device.id])

with self.subTest('Alert should not be displayed without any change'):
self.open(path)
self.hide_loading_overlay()
# The WebDriver automatically accepts the
# beforeunload confirmation dialog. To verify the message,
# we log it to the console and check its content.
#
# our own JS code sets e.returnValue when triggered
# so we just need to ensure it's set as expected
self.web_driver.execute_script(
'django.jQuery(window).on("beforeunload", function(e) {'
' console.warn(e.returnValue); });'
)
self.web_driver.refresh()
for entry in self.get_browser_logs():
if (
entry['level'] == 'WARNING'
and "You haven\'t saved your changes yet!" in entry['message']
):
self.fail('Unsaved changes alert displayed without any change')
5 changes: 4 additions & 1 deletion openwisp_controller/geo/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ def _create_object_location(self, **kwargs):
return ol

def _create_readonly_admin(self, **kwargs):
# remove organization before proceeding to user creation
org1 = kwargs.pop('organization', None)
user = super()._create_readonly_admin(**kwargs)
org1 = self._create_organization()
if not org1:
org1 = self._create_organization()
OrganizationUser.objects.create(user=user, organization=org1, is_admin=True)
return user
Loading