diff --git a/.github/workflows/visual-test.yml b/.github/workflows/visual-test.yml new file mode 100644 index 000000000..5c81c69db --- /dev/null +++ b/.github/workflows/visual-test.yml @@ -0,0 +1,61 @@ +name: Visual testing with Browserstack/Percy +on: + push: + branches: ["master"] + + pull_request: + branches: ["master"] + +jobs: + skiptest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: Check if commit message contain keywords as scope to do visual test + id: check_commit + run: | + message=$(git log -1 --pretty=format:'%s') + re="\[(percy|vrt|visual[-_ ]?test|visual)\]" + if [[ $message =~ $re ]]; then + echo "::set-output name=match::true" + echo "$message -> Match is true" + fi + outputs: + match: ${{ steps.check_commit.outputs.match }} + + build: + runs-on: ubuntu-latest + needs: skiptest + + if: ${{ needs.skiptest.outputs.match == 'true' }} + steps: + + - uses: actions/checkout@v2 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - uses: actions/setup-node@v3 + with: + node-version: 16 + - uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: v1/${{ runner.os }}/pip/${{ hashFiles('**/{requirements,development}.txt') }} + restore-keys: v1/${{ runner.os }}/pip/ + - uses: actions/cache@v2 + with: + path: ~/.npm + key: v1/${{ runner.os }}/node-16/${{ hashFiles('**/package-lock.lock') }} + restore-keys: v1/${{ runner.os }}/node-16/ + - name: Build local static files + run: | + pip3 install -r requirements.txt + ./build + - name: Run tests + run: make test + env: + PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }} + diff --git a/makefile b/makefile new file mode 100644 index 000000000..b574f7f51 --- /dev/null +++ b/makefile @@ -0,0 +1,39 @@ +VENV=.venv/bin +NPM=node_modules/.bin +REQUIREMENTS=$(wildcard requirements.txt) +MARKER=.initialized-with-makefile +VENVDEPS=$(REQUIREMENTS setup.py) +NPMDEPS=$(package-lock.json) + +$(VENV): + python -m venv .venv + $(VENV)/python -m pip install --upgrade pip + +$(VENV)/$(MARKER): $(VENVDEPS) | $(VENV) + $(VENV)/pip install $(foreach path,$(REQUIREMENTS),-r $(path)) + touch $(VENV)/$(MARKER) + +$(NPM): $(NPMDEPS) + npm install + +.PHONY: venv npm install clean serve test + +venv: $(VENV)/$(MARKER) +npm: $(NPM) + +install: npm venv + +clean: + rm -rf $$(cat .gitignore) + +serve-flask: + env FLASK_DEBUG=True ./server + +serve: + $(VENV)/python -m http.server 8000 -d docs + +test: install + $(NPM)/percy exec -- $(VENV)/python test/visual-test.py + + + diff --git a/package.json b/package.json new file mode 100644 index 000000000..24d230ffb --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "devDependencies": { + "@percy/cli": "^1.10.0", + "geckodriver": "^1.21.1" + } +} diff --git a/requirements.txt b/requirements.txt index 00fb3cd49..73b6a20fd 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ Flask feedgen -markupsafe \ No newline at end of file +markupsafe +selenium==3.* +percy-selenium==1.* \ No newline at end of file diff --git a/test/visual-test.py b/test/visual-test.py new file mode 100644 index 000000000..fd82974ee --- /dev/null +++ b/test/visual-test.py @@ -0,0 +1,54 @@ +from http.server import HTTPServer, SimpleHTTPRequestHandler +from threading import Thread +from selenium.webdriver import Firefox, FirefoxOptions +from selenium.webdriver.common.keys import Keys +from percy import percy_snapshot +from functools import partial + + + +# # start monadical webpage in another thread +Handler = partial(SimpleHTTPRequestHandler, directory='./docs') +httpd = HTTPServer(('localhost', 8000), Handler) +thread = Thread(target=httpd.serve_forever) +thread.setDaemon(True) +thread.start() + +# launch firefox headless +ff_options = FirefoxOptions() +ff_options.add_argument('-headless') +browser = Firefox(options=ff_options) + +# go to the main page +browser.get('http://localhost:8000') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Main page') + +# go to the principles page +browser.get('http://localhost:8000/principles.html') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Principles page') + +# go to the portfolio page +browser.get('http://localhost:8000/portfolio.html') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Portfolio page') + +# go to the team page +browser.get('http://localhost:8000/team.html') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Team page') + +# go to the blog main page +browser.get('http://localhost:8000/blog.html') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Blog main page') + +# go to the LY page +browser.get('http://localhost:8000/yak.html') +browser.implicitly_wait(10) +# percy_snapshot(browser, 'Lightning yak page') + +# clean up +browser.quit() +httpd.shutdown() \ No newline at end of file