Skip to content

Commit f9b4856

Browse files
committed
[tests] Refactor Selenium tests for consistency across OpenWISP modules #537
- Removed redundant Selenium dependency in ci.yml, as it's now handled by openwisp-utils. - Updated requirements-test.txt to include Selenium extras in the existing openwisp-utils entry. - Replaced BaseSeleniumTestMixin with openwisp_utils.tests.SeleniumTestMixin where applicable. - Moved Selenium tests from user_batch_test.py to openwisp_radius/tests/test_selenium.py for better organization. - Used self.open() instead of self.web_driver.get(), following OpenWISP conventions. - Replaced direct self.web_driver.find_element() calls with self.find_element(). - Switched to self.wait_for_visibility() instead of manually waiting for elements. These changes improve maintainability and align the tests with other OpenWISP modules. Fixes #537
1 parent 2f6a7cb commit f9b4856

File tree

5 files changed

+260
-1
lines changed

5 files changed

+260
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
csv-user1,password1,csvuser1@example.com,CSV1,User1
2+
csv-user2,password2,csvuser2@example.com,CSV2,User2
3+
csv-user3,password3,csvuser3@example.com,CSV3,User3
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
hash_user1,pbkdf2_sha256$100000$cKdP39chT3pW$2EtVk4Hhm1V65GNfYAA5AHj0uyD60f2CmqumqiB/gRk=,hashuser1@example.com,Hash1,User1
2+
hash_user2,pbkdf2_sha256$100000$aB4cDeF$gHiJkLmNoPqRsTuVwXyZ12345678901234567890123456789=,hashuser2@example.com,Hash2,User2
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
user1,cleartext$password1,user1@example.com,First1,Last1
2+
user2,cleartext$password2,user2@example.com,First2,Last2
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import os
2+
3+
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
4+
from django.urls import reverse
5+
from selenium.webdriver.common.by import By
6+
from selenium.webdriver.support.ui import Select
7+
8+
from openwisp_users.tests.utils import TestOrganizationMixin
9+
from openwisp_utils.tests.selenium import SeleniumTestMixin
10+
11+
current_script_path = os.path.dirname(os.path.abspath(__file__))
12+
13+
14+
class BasicTest(SeleniumTestMixin, StaticLiveServerTestCase, TestOrganizationMixin):
15+
def test_batch_user_creation(self):
16+
self.login()
17+
18+
"""Test the batch user creation feature"""
19+
self.open(reverse('admin:openwisp_users_organization_add'))
20+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
21+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
22+
23+
self.open("/admin/openwisp_radius/radiusbatch/add/")
24+
25+
dropdown = self.find_element(By.ID, "id_strategy")
26+
27+
select = Select(dropdown)
28+
select.select_by_value("prefix")
29+
30+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
31+
prefix_field = self.find_element(By.ID, "id_prefix")
32+
prefix_field.clear()
33+
prefix_field.send_keys("test-user-")
34+
organization = self.find_element(By.ID, "select2-id_organization-container")
35+
organization.click()
36+
37+
option = self.find_element(
38+
By.XPATH,
39+
"//li[contains(@class, 'select2-results__option') and "
40+
"text()='Test Batch']",
41+
)
42+
43+
option.click()
44+
self.find_element(By.ID, "id_number_of_users").send_keys("5")
45+
46+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
47+
48+
success_message = self.wait_for_visibility(By.CLASS_NAME, "success", 10)
49+
self.assertIn("was added successfully", success_message.text)
50+
51+
self.open("/admin/openwisp_users/user/")
52+
53+
user_link = self.wait_for_visibility(
54+
By.XPATH, "//a[contains(text(), 'test-user-')]", 10
55+
)
56+
self.assertIsNotNone(user_link)
57+
58+
self.open("/admin/openwisp_radius/radiusbatch/")
59+
self.find_element(By.CLASS_NAME, "field-name").click()
60+
download_link = self.wait_for_visibility(By.ID, "downloadpdflink", 10)
61+
self.assertIsNotNone(download_link)
62+
63+
def test_standard_csv_import(self):
64+
"""Test standard user import from CSV with all fields provided"""
65+
try:
66+
self.login()
67+
68+
csv_file = os.path.join(current_script_path, "csv_files/users.csv")
69+
70+
self.open(reverse('admin:openwisp_users_organization_add'))
71+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
72+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
73+
74+
self.open("/admin/openwisp_radius/radiusbatch/add/")
75+
76+
dropdown = self.find_element(By.ID, "id_strategy")
77+
78+
select = Select(dropdown)
79+
select.select_by_value("csv")
80+
81+
organization = self.find_element(By.ID, "select2-id_organization-container")
82+
organization.click()
83+
84+
option = self.find_element(
85+
By.XPATH,
86+
"//li[contains(@class, 'select2-results__option') and "
87+
"text()='Test Batch']",
88+
)
89+
90+
option.click()
91+
92+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
93+
94+
csv_file_input = self.find_element(By.ID, "id_csvfile")
95+
96+
csv_file_input.send_keys(csv_file)
97+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
98+
99+
success_message = self.wait_for_visibility(By.CLASS_NAME, "success", 10)
100+
self.assertIn("was added successfully", success_message.text)
101+
self.find_element(By.CLASS_NAME, "field-name").click()
102+
self.open("/admin/openwisp_users/user/")
103+
104+
user1_link = self.wait_for_visibility(
105+
By.XPATH, "//a[contains(text(), 'user1')]", 10
106+
)
107+
self.assertIsNotNone(user1_link)
108+
109+
user2_link = self.find_element(By.XPATH, "//a[contains(text(), 'user2')]")
110+
self.assertIsNotNone(user2_link)
111+
except Exception as e:
112+
print("error ==> ", e)
113+
# self.logout()
114+
115+
def test_import_with_hashed_passwords(self):
116+
"""Test user import with Django-formatted hashed passwords"""
117+
self.login()
118+
119+
csv_file = os.path.join(current_script_path, "csv_files/user_with_hash.csv")
120+
121+
self.open(reverse('admin:openwisp_users_organization_add'))
122+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
123+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
124+
125+
self.open("/admin/openwisp_radius/radiusbatch/add/")
126+
127+
dropdown = self.find_element(By.ID, "id_strategy")
128+
129+
select = Select(dropdown)
130+
select.select_by_value("csv")
131+
self.find_element(By.ID, "id_name").send_keys("Hashed Password Import Test")
132+
133+
organization = self.find_element(By.ID, "select2-id_organization-container")
134+
organization.click()
135+
option = self.find_element(
136+
By.XPATH,
137+
"//li[contains(@class, 'select2-results__option') and "
138+
"text()='Test Batch']",
139+
)
140+
141+
option.click()
142+
csv_file_input = self.find_element(By.ID, "id_csvfile")
143+
csv_file_input.send_keys(csv_file)
144+
145+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
146+
147+
success_message = self.wait_for_visibility(By.CLASS_NAME, "success", 10)
148+
self.assertIn("was added successfully", success_message.text)
149+
150+
self.find_element(By.CLASS_NAME, "field-name").click()
151+
self.open("/admin/openwisp_users/user/")
152+
hash_user1_link = self.wait_for_visibility(
153+
By.XPATH, "//a[contains(text(), 'hash_user1')]", 10
154+
)
155+
self.assertIsNotNone(hash_user1_link)
156+
157+
hash_user2_link = self.find_element(
158+
By.XPATH, "//a[contains(text(), 'hash_user2')]"
159+
)
160+
self.assertIsNotNone(hash_user2_link)
161+
162+
def test_prefix_user_generation(self):
163+
"""Test user generation with prefix strategy"""
164+
self.login()
165+
166+
self.open(reverse('admin:openwisp_users_organization_add'))
167+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
168+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
169+
170+
self.open("/admin/openwisp_radius/radiusbatch/add/")
171+
172+
dropdown = self.find_element(By.ID, "id_strategy")
173+
174+
select = Select(dropdown)
175+
select.select_by_value("prefix")
176+
177+
organization = self.find_element(By.ID, "select2-id_organization-container")
178+
organization.click()
179+
180+
option = self.find_element(
181+
By.XPATH,
182+
"//li[contains(@class, 'select2-results__option') and "
183+
"text()='Test Batch']",
184+
)
185+
option.click()
186+
187+
self.find_element(By.ID, "id_name").send_keys("Prefix Test")
188+
189+
prefix_field = self.find_element(By.ID, "id_prefix")
190+
prefix_field.clear()
191+
prefix_field.send_keys("prefix-user-")
192+
193+
self.find_element(By.ID, "id_number_of_users").send_keys("10")
194+
195+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
196+
197+
success_message = self.wait_for_visibility(By.CLASS_NAME, "success", 10)
198+
self.assertIn("was added successfully", success_message.text)
199+
200+
batch_link = self.wait_for_visibility(
201+
By.XPATH, "//a[contains(text(), 'Prefix Test')]", 10
202+
)
203+
batch_link.click()
204+
user_count_xpath = (
205+
"/html/body/div/div[3]/div[3]/div/div[1]/div[2]/form/div/"
206+
"fieldset/div[6]/div/div/div"
207+
)
208+
209+
user_count = self.wait_for_visibility(By.XPATH, user_count_xpath, 10)
210+
211+
self.assertIn("10", user_count.text)
212+
213+
def test_csv_user_generation(self):
214+
"""Test user generation with CSV upload"""
215+
self.login()
216+
csv_file = os.path.join(current_script_path, "csv_files/csv_user_gen.csv")
217+
self.open(reverse('admin:openwisp_users_organization_add'))
218+
self.find_element(By.ID, "id_name").send_keys("Test Batch")
219+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
220+
221+
self.open("/admin/openwisp_radius/radiusbatch/add/")
222+
223+
dropdown = self.find_element(By.ID, "id_strategy")
224+
225+
select = Select(dropdown)
226+
select.select_by_value("csv")
227+
228+
organization = self.find_element(By.ID, "select2-id_organization-container")
229+
organization.click()
230+
231+
option = self.find_element(
232+
By.XPATH,
233+
"//li[contains(@class, 'select2-results__option') and "
234+
"text()='Test Batch']",
235+
)
236+
option.click()
237+
238+
self.find_element(By.ID, "id_name").send_keys("CSV Test")
239+
csv_file_input = self.find_element(By.ID, "id_csvfile")
240+
csv_file_input.send_keys(csv_file)
241+
242+
self.find_element(By.CSS_SELECTOR, "input[type=submit]").click()
243+
244+
success_message = self.wait_for_visibility(By.CLASS_NAME, "success", 10)
245+
self.assertIn("was added successfully", success_message.text)
246+
247+
self.open("/admin/openwisp_users/user/")
248+
249+
user1_link = self.wait_for_visibility(
250+
By.XPATH, "//a[contains(text(), 'csv-user1')]", 10
251+
)
252+
self.assertIsNotNone(user1_link)

requirements-test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ packaging
55
openwisp-sphinx-theme~=1.0.2
66
freezegun~=1.5.1
77
django-extensions
8-
openwisp-utils[qa] @ https://github.com/openwisp/openwisp-utils/tarball/1.2
8+
openwisp-utils[qa,selenium] @ https://github.com/openwisp/openwisp-utils/tarball/1.2
99
pylinkvalidator
1010
lxml~=5.3.1
1111
cssselect~=1.2.0

0 commit comments

Comments
 (0)