Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Add selenium test for django admin page #50

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
32 changes: 27 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
language: python
dist: xenial
sudo: true
addons:
chrome: stable
apt:
packages:
- chromium-chromedriver
services:
- postgresql
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
env:
- DJANGO='django>=1.11,<2'
- DJANGO='django>=2,<2.1'
- DJANGO='django~=2.1.0'
- DJANGO='--pre django'
matrix:
exclude:
- python: "2.7"
env: DJANGO='django>=2,<2.1'
- python: "3.4"
env: DJANGO='--pre django'
- python: "2.7"
env: DJANGO='--pre django'
- python: "2.7"
env: DJANGO='django~=2.1.0'
- python: "2.7"
env: DJANGO='django>=2,<2.1'
- python: "3.4"
env: DJANGO='django~=2.1.0'
- python: "3.4"
env: DJANGO='--pre django'
- python: "3.7"
env: DJANGO='django>=1.11,<2'
allow_failures:
- env: DJANGO='--pre django'
fast_finish: true
install:
before_script:
# Add link to ChromeDriver in PATH
- ln --symbolic /usr/lib/chromium-browser/chromedriver "${HOME}/bin/chromedriver"
- psql -c 'CREATE DATABASE orderable' -U postgres;
install:
- pip install $DJANGO
- pip install -r requirements.txt
- pip install -e .
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ help:
test:
@coverage run orderable/tests/run.py
@coverage report -m
@bdd/manage.py behave
@flake8

release:
Expand Down
Empty file added bdd/bdd/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions bdd/bdd/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.contrib import admin

from orderable.admin import OrderableAdmin
from .models import Item


admin.site.register(Item, OrderableAdmin)
25 changes: 25 additions & 0 deletions bdd/bdd/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 2.1.2 on 2018-10-26 21:17

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Item',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, db_index=True)),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
]
Empty file added bdd/bdd/migrations/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions bdd/bdd/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from orderable.models import Orderable


class Item(Orderable):
pass
57 changes: 57 additions & 0 deletions bdd/bdd/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY = 'r+n-oywnjf7&b*#(!@zx-wa4j=4_yy7a%j-lep&q8nx6^=lwf5'
ROOT_URLCONF = 'bdd.urls'
STATIC_URL = '/static/'
DATABASES = {'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'orderable',
'HOST': 'localhost'
}}

INSTALLED_APPS = [
# Project.
'bdd',

# 3rd party.
'behave_django',
'orderable',

# Django.
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
7 changes: 7 additions & 0 deletions bdd/bdd/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.conf.urls import url
from django.contrib import admin


urlpatterns = [
url('^admin/', admin.site.urls),
]
15 changes: 15 additions & 0 deletions bdd/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python
import os
import sys

if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bdd.settings')
try:
from django.core.management import execute_from_command_line
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
execute_from_command_line(sys.argv)
14 changes: 14 additions & 0 deletions features/browser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from selenium import webdriver


chrome_options = webdriver.chrome.options.Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1024x768")


class Browser(object):
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.implicitly_wait(5)

def close(context):
context.driver.close()
11 changes: 11 additions & 0 deletions features/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .browser import Browser
from .pages import ItemListPage
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests fail because this isn't an acceptable relative import.



def before_all(context):
context.browser = Browser()
context.item_list_page = ItemListPage()


def after_all(context):
context.browser.close()
29 changes: 29 additions & 0 deletions features/order-list.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Feature: Ordering on the list page

Scenario: Move an item to the end of the list
Given the following items:
| pk |
| 1 |
| 2 |
| 3 |
And we are on the item list page
When item 1 is moved to position 3
Then the items should be ordered thus:
| pk |
| 2 |
| 3 |
| 1 |

Scenario: Move an item to the top of the list
Given the following items:
| pk |
| 1 |
| 2 |
| 3 |
And we are on the item list page
When item 3 is moved to position 1
Then the items should be ordered thus:
| pk |
| 3 |
| 1 |
| 2 |
22 changes: 22 additions & 0 deletions features/pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from browser import Browser
from selenium.webdriver.common.action_chains import ActionChains


class ItemListPage(Browser):
def move_item(self, source, destination):

template = '#neworder-{} .ui-sortable-handle'
find = self.driver.find_element_by_css_selector
offset = 2 if destination > source else -2
(
ActionChains(self.driver)
.click_and_hold(find(template.format(source)))
.move_to_element(find(template.format(destination)))
.move_by_offset(0, offset)
.release()
.perform()
)

def open(self, context):
url = context.get_url('admin:bdd_item_changelist')
self.driver.get(url)
43 changes: 43 additions & 0 deletions features/steps/steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import time

from behave import given, then, when
from django.contrib.auth.models import User
from seleniumlogin import force_login

from bdd.models import Item


@given(u'the following items')
def set_up_items(context):
Item.objects.bulk_create([
Item(pk=row['pk'], sort_order=i)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be i+1, to avoid populating the item with a 0 (which is not a valid value).

for i, row
in enumerate(context.table)
])


@given(u'we are on the item list page')
def go_to_admin_page(context):
user = User.objects.create_superuser(
email='[email protected]',
password='password',
username='myuser',
)
force_login(user, context.browser.driver, context.test.live_server_url)
context.item_list_page.open(context)


@when(u'item {initial_position:d} is moved to position {new_position:d}')
def move_items(context, initial_position, new_position):
context.item_list_page.move_item(initial_position, new_position)
time.sleep(.1)


@then(u'the items should be ordered thus')
def check_item_order(context):
items = list(Item.objects.values_list('pk', flat=True))
expected = []
for row in context.table:
expected.append(int(row['pk']))

assert items == expected, (items, expected)
2 changes: 1 addition & 1 deletion orderable/tests/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from argparse import ArgumentParser
import sys

import django
from django.conf import settings
Expand Down
8 changes: 6 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
behave==1.2.6
behave_django==1.1.0
coverage==3.7.1
flake8==2.2.5
flake8-import-order==0.5.3
django-selenium-login==1.0.2
flake8==3.6.0
flake8-import-order==0.18
hypothesis==2.0.0
psycopg2==2.7.4
selenium==3.14.1
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[wheel]
universal = 1
[flake8]
application-import-names = orderable
application-import-names = orderable, bdd
exclude =
bdd/bdd/migrations
import-order-style = google
max-complexity = 10
max-line-length = 90
Expand Down