Wednesday , July 24 2019
Home / Uncategorized / How to run head-end front-end tests with AWS Cloud9 and AWS CodeBuild

How to run head-end front-end tests with AWS Cloud9 and AWS CodeBuild



Automated testing is a key component of a well designed software development life cycle. When testing front-end applications, a browser is often used in conjunction with test frameworks. A headless browser is one that is used on a server that normally does not need to run visual applications. In this blog post, I'll show you how to configure AWS Cloud9 and AWS CodeBuild to support testing an Angular application with the headless version of Chrome. AWS Cloud9 has a deep integration with services like AWS Lambda and the environment is easily accessible anywhere, from any device connected to the Internet.

AWS Cloud9

By default, Cloud9 runs on an automatically managed Amazon EC2 instance. You can also run it on any Linux machine accessible via SSH.

First of all, create a Cloud9 environment.

  1. Log in to the AWS Management Console, scroll down to Development toolsand choose Cloud 9.
  2. On the following page, choose Create Environment.
  3. Enter a name for your environment and then choose Next step.
  4. On the next page, leave the default values ​​for now and click Next step.
  5. On the following page, choose Create Environment.

It may take a few minutes for the initialization of the environment. Behind the scenes, an EC2 instance is created for you in the region currently selected in the console. In the environment, press Alt-T to open a bash terminal board. For the remaining steps in this post, you will enter the commands in this tab.

There is a lot to do if this is the first time you use Cloud9. If you need help setting up or want to learn more, see the Cloud9 User Guide.

Install and set up Angular

The first thing we will do in our new environment is to install and configure an Angular application.

  1. Update Node to the latest version supported by AWS Lambda. (At the time of writing this, it is 8.10.)
    install nvm 8.10
  2. Install the angular CLI using npm, the node package manager. Install it as a global package with the -g option so that it is available for execution from anywhere in your environment.
    npm install -g @ angular / cli
  3. Use the angular CLI to create a corner application.
    new app mine
    cd my-app /
  4. Run the application to make sure everything works as expected. To view the preview of an application running in Cloud9, the app must be run on a specific port. With Angular, you must disable the default host header control.
    ng serve --port 8080 --host localhost --disable-host-check

    On the toolbar, next to To run, choose Preview and then choose Preview of the application running. You should see something like this:

  5. press Ctrl-C stop serving and then in the my-app directory, try to test your application.
    cd ..
    ng test --watch = false

    Obviously it does not work as you would expect on a normal workstation. The test framework can not find Chrome because we are working on a headless EC2 instance. To start tackling the problem, first install a package called Puppeteer as a development dependency in your application.

    I'd like to give credit here to Alex Bainter, a software developer who wrote a complete blog post to replace PhantomJS with Chromium and headless Karma. His post was extremely useful for me when I first had to figure it out.

  6. Install Puppeteer and his dependencies.
    npm i -D puppeteer
    npm i -D @ angular-devkit / build-angular
  7. You can take a look at the missing Chrome libraries by running the ldd command on the binary file provided with Puppeteer.
    cd node_modules / puppeteer / .local-chromium / linux-564778 / chrome-linux /

    (When you read this post, the version number on that path will probably be different puppeteer / .local-chrome directory to see what it is for the installation.)

    chrome ldd | not grep

    You should see an output that looks like this:

    libXcursor.so.1 => not found
    libXdamage.so.1 => not found
    libXfixes.so.3 => not found
    libcups.so.2 => not found
    libXss.so.1 => not found
    libXrandr.so.2 => not found
    libpangocairo-1.0.so.0 => not found
    libpango-1.0.so.0 => not found
    libcairo.so.2 => not found
    libatk-1.0.so.0 => not found
    libatk-bridge-2.0.so.0 => not found
    libgtk-3.so.0 => not found
    libgdk-3.so.0 => not found
    libgdk_pixbuf-2.0.so.0 => not found

Install Chrome without a head

Now comes the hard part. Installing headless Chrome on an Amazon Linux EC2 instance is not a simple operation. One strategy is to install the various dependencies by compiling from the source, but the dependency chain for Chrome, which includes gtk + and glib, soon escapes. I found another blogger who solved the problem by borrowing from the CentOS and Fedora package repositories. Thanks to Yuanyi for this part of the solution.

  1. Install yum packages to cover basic dependencies.
    sudo yum install -y libXcursor libXamage libcups libXss libXrandr 
    cups-libs dbus-glib libXinerama cairo cairo-gobject pango
  2. Borrow packages from CentOS and Fedora.
    sudo rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/atk-2.22.0-3.el7.x86_64.rpm
    sudo rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-atk-2.22.0-2.el7.x86_64.rpm
    sudo rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-core-2.22.0-1.el7.x86_64.rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/GConf2-3.2.6-7.fc20.x86_64 .rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libXScrnSaver-1.2.2-6.fc20.x86_64 .rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libxkbcommon-0.3.1-1.fc20.x86_64 .rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-client-1.2.0-3.fc20 .x86_64.rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-cursor-1.2.0-3.fc20 .x86_64.rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/gtk3-3.10.4-1.fc20.x86_64 .rpm
    sudo rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/16/Fedora/x86_64/os/Packages/gdk-pixbuf2-2.24.0-1.fc16.x86_64 .rpm
  3. change src / karma.conf.js request Puppeteer and set the CHROME_BIN environment variable. Here is the complete content of that file after the changes.
    const puppeteer = require ("puppeteer");
    process.env.CHROME_BIN = puppeteer.executablePath ();
    
    module.exports = function (config) {
    config.set ({
    basePath: & # 39; & # 39 ;,
    paintings: ['jasmine', ' @angular-devkit/build-angular'],
    plugins: [
                require('karma-jasmine'),
                require('karma-chrome-launcher'),
                require('karma-jasmine-html-reporter'),
                require('karma-coverage-istanbul-reporter'),
               require('@angular-devkit/build-angular/plugins/karma')
            ],
    customer:{
    clearContext: false // leaves the Jasmine Spec Runner output visible in the browser
    },
    coverageIstanbulReporter: {
    relationships: [ 'html', 'lcovonly' ],
    fixWebpackSourcePaths: true
    },
    angularCli: {
    environment: & # 39; dev & # 39;
    },
    to journalists: ['progress', 'kjhtml'],
    port: 8080,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browser: ['ChromeHeadlessNoSandbox'],
    customLaunchers: {
    ChromeHeadlessNoSandbox: {
    base: "ChromeHeadless",
    flags: ['--no-sandbox']
            }
    },
    singleRun: false
    
    });
    
    };
  4. Make a small change to the test specifications in src / app / app.component.spec.ts so that it is checking the title in the called test "should make the title in a h1 tag". To run ng test yet.
    ng test --watch = false

If you see that green SUCCESS indicator, then you did! You have installed Angular and created an application, installed Puppeteer and, by filling in the missing libraries for Chrome, you have made it possible to run headless Chrome tests in Cloud9!

AWS CodeBuild

The next piece of the puzzle is your CI / CD pipeline. When a developer checks the new code, you want to test that code with a continuous integration tool like AWS CodeBuild. With CodeBuild, the problem with Headless Chrome is slightly different from that with Cloud9, because the default build environment for Node apps is an Ubuntu image. You still need to install Chromium and its dependencies, but Ubuntu packages make it easier.

  1. Go to the CodeBuild console and create a new build project. Give it a name and configure the source repository. You will need to store the code for this exercise with one of the providers listed below so that CodeBuild knows where to find it when starting a build. Since you are already connected to the AWS console, AWS CodeCommit is a good option, but you could also choose Amazon S3, Bitbucket or GitHub.
  2. Configure the construction environment. For the operating system, select Ubuntu. For Runtime, choose Node.js. You can specify your own image of the build container, but the buildspec.yml described in step 3 works without the default image.
  3. For the construction specification, provide the following buildspec.yml files in the root directory of the source code repository.
    
    
    
    
    version: 0.2
    phases:
    to install:
    commands:
    
    # Install the angular CLI
    - npm install -g @ angular / cli
    
    # Install the puppeteer as a dependency on dev
    - npm puppeteer i -D
    - npm i -D @ angular-devkit / build-angular
    
    # Print the missing libraries
    - echo "Missing Libs" || ldd ./node_modules/puppeteer/.local-chromium/linux-549031/chrome-linux/chrome | not grep
    
    # Update apt
    - apt-get update
    
    # Update libraries
    - apt-get update
    
    # Install apt-transport-https
    - apt-get install -y apt-transport-https
    
    # Use apt to install Chrome dependencies
    - apt-get install -y libxcursor1
    - apt-get install -y libgtk-3-dev
    - apt-get install -y libxss1
    - apt-get install -y libasound2
    - apt-get install -y libnspr4
    - apt-get install -y libnss3
    - apt-get install -y libx11-xcb1
    
    # Print the missing libraries
    - echo "Missing Libs" || ldd ./node_modules/puppeteer/.local-chromium/linux-549031/chrome-linux/chrome | not grep
    
    # Install project dependencies
    - Installation of npm
    
    pre_build:
    commands
    - echo "Nothing to pre_build"
    
    build:
    commands:
    
    - printenv
    
    # Build the project
    - ng build
    
    # Run headless Chrome tests
    - ng test --watch = false
    - printenv
    
    post_build:
    commands:
    
    - printenv
    
    # Distribute the project on S3
    
    - Self [ ${CODEBUILD_BUILD_SUCCEEDING}=1 ]; then aws s3 sync --delete dist / "s3: // $ {BUCKET_NAME}"; else echo "Ignore aws synchronization"; fi
    
    artifacts:
    File:
    - src / *
    
    

    Feel free to remove those ldd and printenv statements, but it's worth giving a look at the output to better understand what's going on with the build.

  4. Specify the path for artifacts. The following step is not required, but allows you to embed the build project in AWS CodePipeline.
  5. Expand Advanced Settings and configure an environment variable for the website's bucket name.
  6. Configure the buckets. CodeBuild can not write to S3 buckets unless you have explicit service permissions to do so. This is one of the most common causes of compilation errors for projects involving S3. Attach the following policy to the CodeBuild service role to allow access to these buckets. To choose Go on is To save to create the construction project, then log in to the IAM console and look for the role of the CodeBuild service just created for you. Add this as an online criterion.
    
    
    
    
    {
    "Version": "2012-10-17",
    "Declaration": [
    		{
    			"Sid": "VisualEditor0",
    			"Effect": "Allow",
    			"Action": "s3:*",
    			"Resource": [
    				"arn:aws:s3:::YOUR_BUCKET_FOR_ARTIFACTS",
    				"arn:aws:s3:::YOUR_BUCKET_FOR_ARTIFACTS /*"
    			]
    		},
    {
    "Sid": "VisualEditor1",
    "Effect": "Allow",
    "Action": "s3: *",
    "Resource": [
    				"arn:aws:s3:::YOUR_BUCKET_FOR_THE_WEBSITE",
    				"arn:aws:s3:::YOUR_BUCKET_FOR_THE_WEBSITE /*"
    			]
    		}
    ]}
    
    
  7. You should now be able to start compiling and see that the compiled website has been copied to your S3 bucket after completing the build.

Alternative installation of Cloud9 using SSH and Ubuntu

You can run Cloud9 IDE from a Linux computer you create, rather than letting Cloud9 take it over. Create a Cloud9 environment and choose Connect and run on the remote server. For more information on this type of configuration, see Creating an SSH Environment in the AWS Cloud9 User Guide.

After setting up the environment, the work you need to do is much simpler than the Amazon Linux instance, because there are Ubuntu packages that install the required dependencies. Follow the instructions above in this post up to the "Install Headless Chrome" section. Issue this command:

sudo apt install -y libxcursor1 libgtk-3-dev libxss1 libasound2 libnspr4 libnss3

It is not necessary to borrow from any of the CentOS or Fedora repositories.

Make changes to karma.conf.js as described above and you should then be ready to test your application.

Summary

You are now able to perform headless integration testing using Cloud9 by installing Puppeteer and filling up the required Chrome dependencies. You can also extend it to the image of the container used to test your application with CodeBuild. Automated tests are critical to a reliable DevOps pipeline and Cloud9 opens up new possibilities for developers of all types, including front-end developers.

Good programming! -EZB


Source link

Leave a Reply

Your email address will not be published.