ngcp-csc-ui selenium tests will be created here using python3 and nose2 for running tests. firefox only for now, chrome can be added later. this test will create a subscriber, login to csc panel and delete subscriber when it is done Change-Id: Ie10c369b878885aa38892488aea58353d43e74e1changes/02/35302/11
parent
4ef7e354a0
commit
a28cc29bd8
@ -0,0 +1,78 @@
|
||||
# DOCKER_NAME=ngcp-csc-ui-selenium-test-buster
|
||||
FROM docker.mgm.sipwise.com/sipwise-buster:latest
|
||||
|
||||
# Important! Update this no-op ENV variable when this Dockerfile
|
||||
# is updated with the current date. It will force refresh of all
|
||||
# of the base images and things like `apt-get update` won't be using
|
||||
# old cached versions when the Dockerfile is built.
|
||||
ENV REFRESHED_AT 2019-11-21
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install --assume-yes \
|
||||
curl \
|
||||
devscripts \
|
||||
fluxbox \
|
||||
git \
|
||||
libdbus-glib-1-2 \
|
||||
libgtk-3-0 \
|
||||
lsof \
|
||||
net-tools \
|
||||
procps \
|
||||
python3 \
|
||||
python3-pip \
|
||||
vim-tiny \
|
||||
tigervnc-standalone-server \
|
||||
wget \
|
||||
xterm
|
||||
|
||||
RUN adduser --disabled-password --gecos=Selenium-User selenium
|
||||
|
||||
WORKDIR /home/selenium/
|
||||
|
||||
# installing geckodriver (0.26)
|
||||
RUN wget http://deb.sipwise.com/files/geckodriver-v0.26.0-linux64.tar.gz && \
|
||||
tar xvf geckodriver-v0.26.0-linux64.tar.gz && \
|
||||
ln -s /home/selenium/geckodriver /usr/bin/geckodriver && \
|
||||
rm -f geckodriver-v0.26.0-linux64.tar.gz
|
||||
|
||||
# installing firefox (lang=en_US) (70.0.1)
|
||||
RUN wget http://deb.sipwise.com/files/firefox-70.0.1.tar.bz2 && \
|
||||
tar xvf firefox-70.0.1.tar.bz2 && \
|
||||
ln -s /home/selenium/firefox/firefox /usr/bin/firefox && \
|
||||
rm -f firefox-70.0.1.tar.bz2
|
||||
|
||||
# installing nose2 (0.9.1), coverage (4.5.4) and selenium (3.141.0) via pip
|
||||
# considering to package latest version of python3-nose2/selenium/coverage as .deb package
|
||||
# installing coverage first to satisfy dependency for nose2
|
||||
RUN wget http://deb.sipwise.com/files/nose2-0.9.1.tar.gz && \
|
||||
wget http://deb.sipwise.com/files/selenium-3.141.0.tar.gz && \
|
||||
wget http://deb.sipwise.com/files/coverage-4.5.4.tar.gz && \
|
||||
pip3 install coverage-4.5.4.tar.gz && \
|
||||
pip3 install nose2-0.9.1.tar.gz selenium-3.141.0.tar.gz && \
|
||||
rm -f nose2-0.9.1.tar.gz selenium-3.141.0.tar.gz coverage-4.5.4.tar.gz
|
||||
|
||||
RUN echo "cd /code && ./t/selenium/testrunner 1.2.3.4 /code/ tap" >/home/selenium/.bash_history
|
||||
RUN echo "su - selenium" >/root/.bash_history
|
||||
EXPOSE 5999
|
||||
|
||||
COPY t/selenium/jenkins_docker_run /home/selenium/
|
||||
|
||||
################################################################################
|
||||
# Instructions for usage
|
||||
# ----------------------
|
||||
# When you want to build the base image from scratch (jump to the next section if you don't want to build yourself!):
|
||||
# NOTE: run the following command from root folder of git repository:
|
||||
# % docker build --tag="ngcp-csc-ui-selenium-test-buster" -f t/selenium/Dockerfile .
|
||||
# % docker run --rm -p 5999:5999 --shm-size 4g -i -t -v ~/Dokumente/ngcp-csc-ui:/code:rw ngcp-csc-ui-selenium-test-buster bash
|
||||
#
|
||||
# Use the existing docker image:
|
||||
# % docker pull docker.mgm.sipwise.com/ngcp-csc-ui-selenium-test-buster
|
||||
# % docker run --rm -p 5999:5999 --shm-size 4g -i -t -v $(pwd):/code:rw docker.mgm.sipwise.com/ngcp-csc-ui-selenium-test-buster:latest bash
|
||||
#
|
||||
# Inside docker:
|
||||
# su - selenium
|
||||
# cd /code && ./t/selenium/testrunner $IP_OF_NGCP_SYSTEM # IP_OF_NGCP_SYSTEM can be e.g. IP of a `vagrant up ce-trunk` system (eth1)
|
||||
#
|
||||
# On host (where vncviewer can be e.g. from Debian package tigervnc-viewer):
|
||||
# % vncviewer geometry=1280x1024x16 localhost:5999
|
||||
################################################################################
|
@ -0,0 +1,86 @@
|
||||
import os
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
|
||||
def create_subscriber(driver):
|
||||
driver.get(os.environ['CATALYST_SERVER'] + ":1443/logout")
|
||||
driver.get(os.environ['CATALYST_SERVER'] + ":1443")
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="username"]').send_keys('administrator')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="password"]').send_keys('administrator')
|
||||
driver.find_element_by_xpath('//*[@id="submit"]').click()
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="main-nav"]//*[contains(text(),"Settings")]').click()
|
||||
driver.find_element_by_link_text('Customers').click()
|
||||
hoverclick = ActionChains(driver)
|
||||
hoverclick.move_to_element(driver.find_element_by_xpath(
|
||||
'//*[@id="Customer_table"]//tr[1]'))
|
||||
hoverclick.click(driver.find_element_by_xpath(
|
||||
'//*[@id="Customer_table"]//tr[1]//td//a[contains(text(), '
|
||||
'"Details")]')
|
||||
)
|
||||
hoverclick.perform()
|
||||
driver.find_element_by_link_text('Expand Groups').click()
|
||||
driver.execute_script(
|
||||
'arguments[0].scrollIntoView();',
|
||||
driver.find_element_by_link_text('Subscribers')
|
||||
)
|
||||
driver.find_element_by_link_text("Create Subscriber").click()
|
||||
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
|
||||
(By.XPATH, '//*[@id="domainidtable_paginate"]/a[4]')))
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="domainidtable_paginate"]/a[4]').click()
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="domainidtable"]//tr[1]//td//input[@type="checkbox"]'
|
||||
).click()
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="webusername"]').send_keys('testuser')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="webpassword"]').send_keys('testpasswd')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="username"]').send_keys('testuser')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="password"]').send_keys('testpasswd')
|
||||
driver.find_element_by_xpath('//*[@id="save"]').click()
|
||||
|
||||
|
||||
def delete_subscriber(driver):
|
||||
driver.get(os.environ['CATALYST_SERVER'] + ":1443/logout")
|
||||
driver.get(os.environ['CATALYST_SERVER'] + ":1443")
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="username"]').send_keys('administrator')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="password"]').send_keys('administrator')
|
||||
driver.find_element_by_xpath('//*[@id="submit"]').click()
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="main-nav"]//*[contains(text(),"Settings")]').click()
|
||||
driver.find_element_by_link_text('Customers').click()
|
||||
hoverclick = ActionChains(driver)
|
||||
hoverclick.move_to_element(driver.find_element_by_xpath(
|
||||
'//*[@id="Customer_table"]//tr[1]'))
|
||||
hoverclick.click(driver.find_element_by_xpath(
|
||||
'//*[@id="Customer_table"]//tr[1]//td//a[contains(text(), '
|
||||
'"Details")]')
|
||||
)
|
||||
hoverclick.perform()
|
||||
driver.find_element_by_link_text('Expand Groups').click()
|
||||
driver.execute_script(
|
||||
'arguments[0].scrollIntoView();',
|
||||
driver.find_element_by_link_text('Subscribers')
|
||||
)
|
||||
WebDriverWait(driver, 1)
|
||||
hoverclick = ActionChains(driver)
|
||||
hoverclick.move_to_element(driver.find_element_by_xpath(
|
||||
'//*[@id="subscribers_table"]//tr[1]'))
|
||||
hoverclick.click(driver.find_element_by_xpath(
|
||||
'//*[@id="subscribers_table"]//tr[1]//td//a[contains(text(), '
|
||||
'"Terminate")]')
|
||||
)
|
||||
hoverclick.perform()
|
||||
driver.find_element_by_xpath('//*[@id="dataConfirmOK"]').click()
|
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# This script is used for running the tests with
|
||||
# proper arguments from Jenkins under user 'selenium'
|
||||
|
||||
set -e
|
||||
|
||||
su - selenium -c "cd /code && ./t/selenium/testrunner $*" || RC=$?
|
||||
|
||||
## Jenkins will detect errors in produced artifacts if any
|
||||
## as a result the Jenkins job will be "yellow" instead of "red".
|
||||
[ -n "${RC}" ] && echo "Masking non-zero exit code '${RC}'"
|
||||
exit 0 # ${RC:-0}
|
@ -0,0 +1,9 @@
|
||||
[unittest]
|
||||
plugins = nose2.plugins.junitxml
|
||||
exclude-plugins = nose2.plugins.failfast
|
||||
|
||||
[junit-xml]
|
||||
always-on = True
|
||||
keep_restricted = False
|
||||
path = /results/selenium.xml
|
||||
test_fullname = True
|
@ -0,0 +1,12 @@
|
||||
[unittest]
|
||||
plugins = nose2.plugins.junitxml
|
||||
exclude-plugins = nose2.plugins.failfast
|
||||
|
||||
[junit-xml]
|
||||
always-on = False
|
||||
keep_restricted = False
|
||||
path = selenium.xml
|
||||
test_fullname = True
|
||||
|
||||
[pretty-assert]
|
||||
always-on = True
|
@ -0,0 +1,76 @@
|
||||
import unittest
|
||||
import os
|
||||
import nose2
|
||||
import functions.Collections as Collections
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
|
||||
class test_login(unittest.TestCase):
|
||||
def setUp(self):
|
||||
profile = webdriver.FirefoxProfile()
|
||||
profile.accept_untrusted_certs = True
|
||||
caps = DesiredCapabilities().FIREFOX
|
||||
caps["pageLoadStrategy"] = "normal"
|
||||
self.driver = webdriver.Firefox(
|
||||
capabilities=caps, firefox_profile=profile, log_path='/dev/null')
|
||||
self.driver.implicitly_wait(10)
|
||||
self.driver.set_page_load_timeout(10)
|
||||
|
||||
def test_login(self):
|
||||
driver = self.driver
|
||||
Collections.create_subscriber(driver)
|
||||
driver.find_element_by_link_text('Expand Groups').click()
|
||||
domainname = driver.find_element_by_xpath(
|
||||
'//*[@id="subscribers_table"]//tr[1]/td[3]').text
|
||||
driver.get(os.environ['CATALYST_SERVER'])
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="text"]'
|
||||
).send_keys('invalid')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="password"]'
|
||||
).send_keys('user')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login"]//div//button').click()
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="text"]'
|
||||
).send_keys(Keys.CONTROL + "a")
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="text"]'
|
||||
).send_keys(Keys.DELETE)
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="text"]'
|
||||
).send_keys('testuser@' + domainname)
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="password"]'
|
||||
).send_keys(Keys.CONTROL + "a")
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="password"]'
|
||||
).send_keys(Keys.DELETE)
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login-form"]//div//input[@type="password"]'
|
||||
).send_keys('testpasswd')
|
||||
driver.find_element_by_xpath(
|
||||
'//*[@id="csc-login"]//div//button').click()
|
||||
self.assertEqual("testuser", (driver.find_element_by_xpath(
|
||||
'//*[@id="csc-header-toolbar"]//div//span[contains(text(), '
|
||||
'"testuser")]').text)
|
||||
)
|
||||
WebDriverWait(driver, 1)
|
||||
|
||||
def tearDown(self):
|
||||
driver = self.driver
|
||||
try:
|
||||
Collections.delete_subscriber(driver)
|
||||
driver.close()
|
||||
except Exception:
|
||||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
nose2.main()
|
@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -f /.dockerenv ] && ! grep -q 'devices:/docker' /proc/1/cgroup ; then
|
||||
echo "Not running inside docker, exiting to avoid data damage." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
PASSWORD="selenium"
|
||||
|
||||
if [ -z "${1:-}" ] ; then
|
||||
echo "Usage: $0 <testsystem> [<output_directory>] [junit] [test_plan]" >&2
|
||||
echo
|
||||
echo "Usage examples:
|
||||
|
||||
$0 1.2.3.4
|
||||
$0 1.2.3.4 /code/ tap"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVER="${1}"
|
||||
OUTPUT_DIRECTORY="${2:-/code/}"
|
||||
OUTPUT_TYPE=${3:-}
|
||||
shift; shift; shift # remove first three argv to use ${@} below.
|
||||
|
||||
# vnc
|
||||
echo "Setting VNC password"
|
||||
printf '%s\n%s\n\n' "${PASSWORD}" "${PASSWORD}" | vncpasswd >/dev/null
|
||||
PASSWORD_ENCODED=$(hexdump -v -e '"\\""x" 1/1 "%02X"' < "${HOME}/.vnc/passwd")
|
||||
xvnc_process=$(pgrep -f 'Xtigervnc :99' || true)
|
||||
export DISPLAY=":99"
|
||||
if [ -n "${xvnc_process:-}" ] ; then
|
||||
echo "Warning: existing VNC server found, not restarting Xtigervnc process (PID: $xvnc_process)."
|
||||
else
|
||||
echo "Starting VNCserver on display :99"
|
||||
vncserver -localhost no -geometry 1280x1024 :99
|
||||
fi
|
||||
|
||||
echo "Firefox version:"
|
||||
firefox --version
|
||||
|
||||
# ensure we don't leave any process behind causing problems with re-execution
|
||||
pkill -f 'geckodriver' || true
|
||||
DISPLAY=:99 ~/geckodriver -p 4444 --log fatal &
|
||||
#DISPLAY=:99 ~/geckodriver -p 5555 --log fatal &
|
||||
#DISPLAY=:99 ~/geckodriver -p 6666 --log fatal &
|
||||
#DISPLAY=:99 ~/geckodriver -p 7777 --log fatal &
|
||||
|
||||
echo "################################################################################"
|
||||
echo "Finished main setup, now running tests ..."
|
||||
echo "Selenium server log file available at /home/selenium/selenium.log"
|
||||
echo "Watch at test runs by connecting via VNC (password: '${PASSWORD}'):"
|
||||
echo "echo -e '$PASSWORD_ENCODED' >/tmp/vncpasswd ; vncviewer geometry=1280x1024x16 passwd=/tmp/vncpasswd localhost:5999"
|
||||
|
||||
RC=0
|
||||
export CATALYST_SERVER="https://${SERVER}"
|
||||
cd t/selenium
|
||||
|
||||
if [ "${OUTPUT_TYPE:-}" = "junit" ] ; then
|
||||
export JENKINS=1
|
||||
nose2 -v -c nose2cfg/jenkinstest.cfg | \
|
||||
tee -a "${OUTPUT_DIRECTORY}/selenium.xml"
|
||||
RC="${PIPESTATUS[0]}"
|
||||
else
|
||||
nose2 -v -c nose2cfg/localtest.cfg || RC=$?
|
||||
fi
|
||||
|
||||
echo "Finished test execution, test execution returned with exit code ${RC}."
|
||||
if [ -f "${OUTPUT_DIRECTORY}/selenium.xml" ] ; then
|
||||
echo "Test results available at '${OUTPUT_DIRECTORY}/selenium.xml'"
|
||||
fi
|
||||
|
||||
echo "################################################################################"
|
||||
|
||||
exit "${RC}"
|
Loading…
Reference in new issue