Skip to content

Commit

Permalink
Split selenium tests into separate CI job
Browse files Browse the repository at this point in the history
  • Loading branch information
codingjoe committed Jun 6, 2023
1 parent 92fec2c commit abbb812
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 10 deletions.
27 changes: 26 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,36 @@ jobs:
- run: python -m pip install .[test] codecov
- run: python -m pip install django~=${{ matrix.django-version }}.0
- run: python -m pytest
- run: python -m pytest -m "not selenium"
env:
PATH: $PATH:$(pwd)/bin
- run: codecov

selenium:
needs:
- pytest
strategy:
matrix:
python-version:
- "3.x"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Chrome
run: sudo apt-get install -y google-chrome-stable
- name: Install Selenium
run: |
mkdir bin
curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
unzip chromedriver_linux64.zip -d bin
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install -e .[test]
- run: python -m pytest -m selenium
- uses: codecov/codecov-action@v3


analyze:
name: CodeQL Analyze
needs:
Expand Down
6 changes: 5 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
from s3file.storages import get_aws_location


def pytest_configure(config):
config.addinivalue_line("markers", "selenium: skip if selenium is not installed")


@pytest.fixture(scope="session")
def driver():
chrome_options = webdriver.ChromeOptions()
chrome_options.headless = True
chrome_options.add_argument("--headless=new")
try:
b = webdriver.Chrome(options=chrome_options)
except WebDriverException as e:
Expand Down
7 changes: 6 additions & 1 deletion tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,15 @@ def test_accept(self):
"application/pdf,image/*"
)

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

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

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

@pytest.mark.selenium
def test_file_insert_submit_value(
self, driver, live_server, upload_file, freeze_upload_folder
):
Expand All @@ -179,6 +182,7 @@ def test_file_insert_submit_value(
assert "save_continue" in driver.page_source
assert "continue_value" in driver.page_source

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

@pytest.mark.selenium
def test_multi_file(
self,
driver,
Expand All @@ -208,7 +213,7 @@ def test_multi_file(
another_upload_file,
yet_another_upload_file,
):
driver.get(live_server + self.url)
driver.get(live_server + reverse("upload-multi"))
file_input = driver.find_element(By.XPATH, "//input[@name='file']")
file_input.send_keys(
" \n ".join(
Expand Down
32 changes: 25 additions & 7 deletions tests/testapp/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,32 @@
) + forms.ClearableFileInput.__bases__


class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True


class UploadForm(forms.ModelForm):
class Meta:
model = FileModel
fields = ("file", "other_file")
widgets = {
"file": MultipleFileInput(attrs={"multiple": True}),
}


class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True


class MultipleFileField(forms.FileField):
def __init__(self, *args, **kwargs):
kwargs.setdefault("widget", MultipleFileInput())
super().__init__(*args, **kwargs)

def clean(self, data, initial=None):
single_file_clean = super().clean
if isinstance(data, (list, tuple)):
result = [single_file_clean(d, initial) for d in data]
else:
result = single_file_clean(data, initial)
return result


class MultiUploadForm(forms.Form):
file = MultipleFileField(
required=False, widget=MultipleFileInput(attrs={"multiple": True})
)
other_file = forms.FileField(required=False)
1 change: 1 addition & 0 deletions tests/testapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@

urlpatterns = [
path("", views.ExampleFormView.as_view(), name="upload"),
path("multi/", views.MultiExampleFormView.as_view(), name="upload-multi"),
]
18 changes: 18 additions & 0 deletions tests/testapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,21 @@ def form_valid(self, form):
status=201,
encoder=FileEncoder,
)


class MultiExampleFormView(generic.FormView):
form_class = forms.MultiUploadForm
template_name = "form.html"

def form_valid(self, form):
return JsonResponse(
{
"POST": self.request.POST,
"FILES": {
"file": self.request.FILES.getlist("file"),
"other_file": self.request.FILES.getlist("other_file"),
},
},
status=201,
encoder=FileEncoder,
)

0 comments on commit abbb812

Please sign in to comment.