Skip to content

Commit abbb812

Browse files
committed
Split selenium tests into separate CI job
1 parent 92fec2c commit abbb812

File tree

6 files changed

+81
-10
lines changed

6 files changed

+81
-10
lines changed

.github/workflows/ci.yml

+26-1
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,36 @@ jobs:
9292
9393
- run: python -m pip install .[test] codecov
9494
- run: python -m pip install django~=${{ matrix.django-version }}.0
95-
- run: python -m pytest
95+
- run: python -m pytest -m "not selenium"
9696
env:
9797
PATH: $PATH:$(pwd)/bin
9898
- run: codecov
9999

100+
selenium:
101+
needs:
102+
- pytest
103+
strategy:
104+
matrix:
105+
python-version:
106+
- "3.x"
107+
runs-on: ubuntu-latest
108+
steps:
109+
- uses: actions/checkout@v3
110+
- name: Install Chrome
111+
run: sudo apt-get install -y google-chrome-stable
112+
- name: Install Selenium
113+
run: |
114+
mkdir bin
115+
curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
116+
unzip chromedriver_linux64.zip -d bin
117+
- uses: actions/setup-python@v4
118+
with:
119+
python-version: ${{ matrix.python-version }}
120+
- run: python -m pip install -e .[test]
121+
- run: python -m pytest -m selenium
122+
- uses: codecov/codecov-action@v3
123+
124+
100125
analyze:
101126
name: CodeQL Analyze
102127
needs:

tests/conftest.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
from s3file.storages import get_aws_location
1111

1212

13+
def pytest_configure(config):
14+
config.addinivalue_line("markers", "selenium: skip if selenium is not installed")
15+
16+
1317
@pytest.fixture(scope="session")
1418
def driver():
1519
chrome_options = webdriver.ChromeOptions()
16-
chrome_options.headless = True
20+
chrome_options.add_argument("--headless=new")
1721
try:
1822
b = webdriver.Chrome(options=chrome_options)
1923
except WebDriverException as e:

tests/test_forms.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,15 @@ def test_accept(self):
135135
"application/pdf,image/*"
136136
)
137137

138+
@pytest.mark.selenium
138139
def test_no_js_error(self, driver, live_server):
139140
driver.get(live_server + self.url)
140141

141142
with pytest.raises(NoSuchElementException):
142143
error = driver.find_element(By.XPATH, "//body[@JSError]")
143144
pytest.fail(error.get_attribute("JSError"))
144145

146+
@pytest.mark.selenium
145147
def test_file_insert(
146148
self, request, driver, live_server, upload_file, freeze_upload_folder
147149
):
@@ -157,6 +159,7 @@ def test_file_insert(
157159
error = driver.find_element(By.XPATH, "//body[@JSError]")
158160
pytest.fail(error.get_attribute("JSError"))
159161

162+
@pytest.mark.selenium
160163
def test_file_insert_submit_value(
161164
self, driver, live_server, upload_file, freeze_upload_folder
162165
):
@@ -179,6 +182,7 @@ def test_file_insert_submit_value(
179182
assert "save_continue" in driver.page_source
180183
assert "continue_value" in driver.page_source
181184

185+
@pytest.mark.selenium
182186
def test_progress(self, driver, live_server, upload_file, freeze_upload_folder):
183187
driver.get(live_server + self.url)
184188
file_input = driver.find_element(By.XPATH, "//input[@name='file']")
@@ -199,6 +203,7 @@ def test_progress(self, driver, live_server, upload_file, freeze_upload_folder):
199203
response = json.loads(driver.find_elements(By.CSS_SELECTOR, "pre")[0].text)
200204
assert response["POST"]["progress"] == "1"
201205

206+
@pytest.mark.selenium
202207
def test_multi_file(
203208
self,
204209
driver,
@@ -208,7 +213,7 @@ def test_multi_file(
208213
another_upload_file,
209214
yet_another_upload_file,
210215
):
211-
driver.get(live_server + self.url)
216+
driver.get(live_server + reverse("upload-multi"))
212217
file_input = driver.find_element(By.XPATH, "//input[@name='file']")
213218
file_input.send_keys(
214219
" \n ".join(

tests/testapp/forms.py

+25-7
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,32 @@
1010
) + forms.ClearableFileInput.__bases__
1111

1212

13-
class MultipleFileInput(forms.ClearableFileInput):
14-
allow_multiple_selected = True
15-
16-
1713
class UploadForm(forms.ModelForm):
1814
class Meta:
1915
model = FileModel
2016
fields = ("file", "other_file")
21-
widgets = {
22-
"file": MultipleFileInput(attrs={"multiple": True}),
23-
}
17+
18+
19+
class MultipleFileInput(forms.ClearableFileInput):
20+
allow_multiple_selected = True
21+
22+
23+
class MultipleFileField(forms.FileField):
24+
def __init__(self, *args, **kwargs):
25+
kwargs.setdefault("widget", MultipleFileInput())
26+
super().__init__(*args, **kwargs)
27+
28+
def clean(self, data, initial=None):
29+
single_file_clean = super().clean
30+
if isinstance(data, (list, tuple)):
31+
result = [single_file_clean(d, initial) for d in data]
32+
else:
33+
result = single_file_clean(data, initial)
34+
return result
35+
36+
37+
class MultiUploadForm(forms.Form):
38+
file = MultipleFileField(
39+
required=False, widget=MultipleFileInput(attrs={"multiple": True})
40+
)
41+
other_file = forms.FileField(required=False)

tests/testapp/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77

88
urlpatterns = [
99
path("", views.ExampleFormView.as_view(), name="upload"),
10+
path("multi/", views.MultiExampleFormView.as_view(), name="upload-multi"),
1011
]

tests/testapp/views.py

+18
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,21 @@ def form_valid(self, form):
2929
status=201,
3030
encoder=FileEncoder,
3131
)
32+
33+
34+
class MultiExampleFormView(generic.FormView):
35+
form_class = forms.MultiUploadForm
36+
template_name = "form.html"
37+
38+
def form_valid(self, form):
39+
return JsonResponse(
40+
{
41+
"POST": self.request.POST,
42+
"FILES": {
43+
"file": self.request.FILES.getlist("file"),
44+
"other_file": self.request.FILES.getlist("other_file"),
45+
},
46+
},
47+
status=201,
48+
encoder=FileEncoder,
49+
)

0 commit comments

Comments
 (0)