Git Product home page Git Product logo

adobe / frontend-regression-validator Goto Github PK

View Code? Open in Web Editor NEW
67.0 10.0 10.0 279.23 MB

Visual regression tool used to compare baseline and updated instances of a website in a deployment pipeline.

License: Apache License 2.0

Python 62.86% CSS 0.41% HTML 8.77% JavaScript 22.56% Dockerfile 0.40% Jupyter Notebook 4.99%
regression visual-regression visual-regression-testing machine-learning segmentation pipeline rest-api fred validator website

frontend-regression-validator's Introduction

Python 3 Version 2.0

Frontend Regression Validator (FRED)

FRED is an opensource visual regression tool used to compare two instances of a website. FRED is responsible for automatic visual regression testing, with the purpose of ensuring that functionality is not broken by comparing a current(baseline) and an updated version of a website. FRED compares the following:

  • Console and network logs
  • Visual: screenshot analysis
  • Visual AI: screenshot analysis using Machine Learning techniques

The visual analysis computes the Normalized Mean Squared error and the Structural Similarity Index on the screenshots of the baseline and updated sites, while the visual AI looks at layout and content changes independently by applying image segmentation Machine Learning techniques to recognize high-level text and image visual structures. This reduces the impact of dynamic content yielding false positives.

Use FRED if you need:

  • Screenshot comparision
  • Automatic layout/content verification

FRED is designed to be scalable. It has an internal queue and can process websites in parallel depending on the amount of RAM and CPUs (or GPUs) available.

NOTE: The entire repo for version 1.0 is available in _fred-v1. Please note that v2.x (current version) does not contain the code to train/retrain the ML model. If you need to do that, please check the original code in the v1 folder. The models are identical, so if you create your custom-trained model, plug it in v2 and it will work.

Start FRED

You can start FRED either as a docker or as a local process.

Quickstart Docker

If you just want to clone and run the software, we have provided a Dockerfile. To run it:

git clone https://github.com/adobe/frontend-regression-validator.git
cd frontend-regression-validator/docker
docker build --no-cache -t fred .
docker run -p 5000:5000 -m 8g --memory-reservation=8g --oom-kill-disable=True --memory-swap 8G fred

If you still encounter issues with out of memory errors, allocate more memory from the UI Docker app. Simply click the Docker icon in your toolbar, go to Preferences-Advanced and then pull the slider to 8GB or more, especially if you plan to use ML (optional). We recommended running it locally instead of using the Dockerfile or to increase the memory allocated to docker to at least 8GB, prefferably 16GB.

Start Locally

Ensure you have installed chromedriver. If you don't have it, install it on MAC with:

brew tap homebrew/cask && brew cask install chromedriver

or on Linux with:

sudo apt-get install chromium-chromedriver

then run the following:

git clone https://github.com/adobe/frontend-regression-validator.git
cd frontend-regression-validator
pip install -r requirements.txt
cd fred/ml
cat model_files.bz2.parta* > model_files.bz2
tar xjf model_files.bz2
cd ..
python3 run.py

This will launch a Flask instance that answers to requests as well as offering a web user interface. Quicknote: use --port to specify the listening port, by default it listens on 5000. Please view more details about FRED's startup parameters here.

Use FRED

Interaction with FRED is done either by web UI or by API calls. The UI simply allows a user to send calls to the API endpoint and view results.

To open the web interface navigate to http://0.0.0.0:5000/static/submit.html (adjust port accordingly). Fill in all the required fields, run the job and wait until it completes. View results by clicking the Jobs link in the header.

To use the API please view the dedicated API readme here.

Overlook on how FRED operates

FRED waits until it receives a request to perform a website comparison (POST call to /api/verify). It starts the crawl process. We can request to see all jobs with a GET call to /api/viewjobs and get the status of a particular job with a GET to /api/results providing the job id as a parameter.

  • As such, the input to FRED is a pair of URLs to compare.

  • The process begins with FRED crawling the URLs to extract a number of pages to compare, and then renders each page and takes screenshots.

  • The console and network logs are compared.

  • Each screenshot is analyzed (as pairs of baseline/updated screenshots, for each specified resolution).

  • If enabled, each screenshot pair also undergoes ML analysis

  • Results are saved locally (a user must periodically check via the API until the status is set to Done and/or some error is set.)

  • A result is a json object that in the report key contains a number of scores. The overall_divergence score is the weighted sum of the network, visual and ai-visual(if enabled) divergences. A score of 0 means a perfect match (no difference between baseline and updated), while higher scores, up to 100 highlight differences.

  • If needed use the visual interface to quickly investigate results. Otherwise, the report also contains links to the raw images as well as analysis images that highlight differences if you want to use FRED in an automated fashion.

Because FRED is designed to be scalable, it is logically split in two components: crawler and ML. The crawler component is the main entry point that the user interacts with. The ML component, while being the same code as the crawler component, is simply another endpoint listening for API calls. The logic behind this split is that GPUs are expensive while CPUs are not. So we can have many crawlers that in turn make requests to a few GPU enabled FRED instances (called ML components) to perform the ML analysis.

For example, imagine a scenario where we have 1000 websites to analyze daily. We create 10 virtual machines, each with 32GB RAM and 8 vCPUs. Each instance will receive 100 /api/verify calls. Assume we set --crawler_threads to 5, meaning we can concurrently crawl 5 websites. Furthermore, as we only have a single GPU machine with 4 GPUs, we launch on it a FRED instance, which we'll call the ML component. On this instance we set --ai_threads to 4, meaning we concurrently run 4 ML validations. Now, on each of the POST API requests to the crawler components we set the ml_address to the ml component's address. What will now happen is that whenever a crawler component finishes to crawl and analyize (non-AI) a website pair, it will send the ML component its screenshots and request to analyze them. The ml component will add this request in its queue and when a GPU is available it will run the comparison on it. When finished, it will automatically report back to the originating crawler component its analysis. Basically, this approach scales performance linearly with the number of available testing machines.

Performance analysis

FRED runtimes vary greatly on the complexity of the site. Most of the time is spent in the crawler component, as (unfortunately) loading a website is not a deterministic process. Sometimes, a website simply hangs, or a popup randomly appears, or some external resource refuses to load. Internally, we have the only remedy to this: a sort of try-catch that reloads a website if something horrible happens. But this, coupled with the fact that we wait a few seconds after the page says it loaded, plus the repeated screenshots to discover dynamic content, dramatically increase crawl time.

The crawl part usually takes 2-10 minutes, depending on the number of pages crawled.

Visual analysis (with each screenshot limited to at most 20 Megapixels) takes ~5-10 seconds per image pair. Each extra resolution means another set of image pairs.

AI (ML) visual analysis takes 0-30 seconds per image pair on a GPU. Any GPU will do, even an old K80 will run very fast, as the ML par is a U-NET (stacked convolutional layers). You can always run on a CPU, but instead of 30 seconds per image pair, you might wait 5 minutes per image pair.

Overall, the rule of thumb for a ML-enabled crawl, start to finish, is 1 minute or less per page.

frontend-regression-validator's People

Contributors

alexandrumeterez avatar dumitrescustefan avatar rscctest avatar tiberiu44 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frontend-regression-validator's Issues

Error status message

Running several tests (locally) I've come up with several different errors in the console, but the message on the UI seems to always be the same : "Invalid website".

I think it should reflect the actual error thrown. For example:

Traceback (most recent call last):
  File "worker_predict.py", line 78, in <module>
    work(args.baseline_dir, args.updated_dir, args.prefix)
  File "worker_predict.py", line 54, in work
    updated_network_log_file)
  File "/Users/sdumitre/work/frontend-regression-validator/fred/process/process.py", line 8, in __init__
    self.baseline_js_logs = JavascriptLogPreprocessor(baseline_js_log_file)
  File "/Users/sdumitre/work/frontend-regression-validator/fred/data/log_preprocess.py", line 7, in __init__
    self.logs = json.load(open(log_file, 'r'))
FileNotFoundError: [Errno 2] No such file or directory: './tmp/1_baseline/buttons_1_js_log.json'

gives the Status: Invalid website message. Guess this is a low priority issue, but it for non-coder users this error message is confusing.

Invalid website message when running a local test job

Hi,

When entering a local website, i get the job failed with Status: Invalid website.

I opened two dummy websites with php -S 127.0.0.1:8100 (and port 8101), with two index.html files containing:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title></title>
</head>
<body>
<img src="new_shift.png"/>
</body>
</html>

each with a different png file. They render okay in the browser, but in fred's job interface I get:

Baseline URL: http://127.0.0.1:8100/index.html
Updated URL: http://127.0.0.1:8101/index.html
Max depth for crawler: 1
Max URLs for crawler: 1
Prefix: out1
Status: Invalid website

Error from the local FRED instance (started with run.py):

127.0.0.1 - - [13/Jan/2020 10:33:36] "POST /api/verify HTTP/1.1" 200 -
Traceback (most recent call last):
  File "worker_crawl.py", line 117, in <module>
    args.auth_baseline_password, args.auth_updated_username, args.auth_updated_password)
  File "worker_crawl.py", line 32, in work
    crawled_baseline = get_recursive_urls(baseline_url, max_depth, max_urls)[:max_urls]
  File "/Users/sdumitre/work/frontend-regression-validator/fred/crawler/crawler.py", line 51, in get_recursive_urls
    asyncio.get_event_loop().run_until_complete(get_page(page, parent_url))
  File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
    return future.result()
  File "/Users/sdumitre/work/frontend-regression-validator/fred/crawler/crawler.py", line 19, in get_page
    await page.goto(url)
  File "/Users/sdumitre/virtual/p3/lib/python3.7/site-packages/pyppeteer/page.py", line 856, in goto
    raise PageError(result)
pyppeteer.errors.PageError: net::ERR_CONNECTION_REFUSED at http://:@127.0.0.1

Tx

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.