You are currently viewing Testing OAuth Integration Flows With Zombie.js

Testing OAuth Integration Flows With Zombie.js

To integrate testing your Node.js web app, OAuth Javascript, there are many good reasons to use headless browsing tools like Zombie.js. Headless browsers can be fast and are designed to handle Node’s asynchronous patterns, unlike Selenium which is more synchronous. However, there is one problem: they are not the same. After using Zombie.js to test various projects at My Country Mobile (MCM), I cannot count how many times it has failed to behave like a real browser.

Testing third-party OAuth Javascript login streams have been my biggest problem. For social login buttons like LinkedIn or Google+, the user must click through permission-granting pages with security features. We quickly discovered that Zombie was interfering with the login process when testing them. We looked at the source of these login pages and found that they had measures to stop the page from being loaded in an iFrame (frame killer) and other obfuscated JavaScript snippets.

This problem solves, but it takes some flexibility and lots of trial and error. As a resource, I have created a Github repo that demonstrates the overarching principles through two example flows Google and LinkedIn.

Side Note: Why test OAuth Javascript?

Social logins have become increasingly popular for web apps, and they can sometimes be the only way to sign in. Even though social login is a popular option, it shouldn’t stop you from writing meaningful and detailed integration tests in any browser. For example, OAuth Javascript login flows give the application access to social profiles. You should test against this information if your application uses it. Although unit tests are helpful (where you simulate a social login callback with a library such as Nock), they don’t provide the same depth of coverage as pure integration tests. However, you can be sure that the application offers the desired experience for the user.

80-web-illustration-e1643712568793 (1)

Tip #1: Test the user’s OAuth Javascript

It’s unlikely that you can automate user creation because CAPTCHAs are a standard feature on social account signup pages. However, it would help to remember a few things when creating test accounts.

  • Ensure you read the terms and conditions of APIs that apply to the social service you wish to log in to. For example, some companies may have requirements that you must meet to create developer test accounts, such as LinkedIn.
  • When repeating automated testing, keep in mind the rate limits. You can try multiple accounts to solve the problem and swap them for other test suites.
  • Securely store your account information. We ended up keeping our account information in S3 and rotating it out for different integration tests.

Tip #2: Approve your app before you submit

This is the essential tool to integrate Zombie. After creating your accounts, open a standard browser and go through the login flow for each performance. Instead of waiting for Zombie to authorize your app with OAuth Javascript, allow it now. The authorization saves to your social account. This will be especially helpful in Google’s situation. Zombie can skip the authorization page entirely, which is crucial as it contains the frame killer and other security measures.

You’ll get results like these if you don’t preapprove your app using a real browser.

0 passing (19s)

Two failing

  1. The login flow to google OAuth Javascript reaches the profile page. profile title
  2. + Actual – Expected
  3. + “My Profile Page.”
  4. – “Request for Permission”
  5. Context
  6. The LinkedIn OAuth Javascript login flow reaches the profile page:
  7. Profile title
  8. + Actual – Expected
  9. + “My Profile Page.”
  10. -“Authorize | LinkedIn.”
  11. Context

… Zombie is stopped by OAuth Javascript login page security measures and cannot proceed.

Tip #3: Take a look at the page

Your browser may not have ahead, but that doesn’t mean it can’t give you an idea of what is being displayed. Zombie allows you to use browser.html to dump the HTML content on your current page OAuth Javascript. This can be used to your advantage. Therefore, My favorite addition to an integration test suite is a block of code that runs after a test fails and leaves the page’s contents. So when my first attempt at an integration flow fails, which it often does, I can see the page is stuck and whether it matches my assumptions. This was how we found the frame killer, and it helped us at every step of the way as we created the solution.

349-2-e1643711059150 (1)

Tip #4: The user agent is important

Configure Zombie to use a modern desktop browser’s user agent. In addition, your user agent string can sometimes cause unwanted behavior. For example, Google’s login flow will ask you to use the device location for mobile clients. This can again cause unexpected interactions in your integration flow.

Tip #5 – Get creative OAuth Javascript

Even if your apps are preapproval, you will still need to enter your username/password in the OAuth login flow. Sometimes this is not possible. LinkedIn, for instance, has its frame killer page. Although we couldn’t log into LinkedIn using the OAuth Javascript flow, what if we had LinkedIn session cookies in our browser? The OAuth login flow skips full of cookie use, as demonstrated by our experience. So We tried several ways to log in to LinkedIn and obtain a session cookie that Zombie could manage. In the end, we logged in to Zombie’s mobile site by spoofing a user agent, got the cookie, and also returned to our web app. This code is demonstrated in the repo.

Similar anomalies may occur if you expand your social network to include other social media providers like Facebook also Twitter. Every OAuth Javascript login flow may not be the same. Flexibility and creativity can make a big difference in finding a solution. Know more about Best VoIP Based Alternatives Google Voice.