Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Maze Runner end to end test suite #351

Merged
merged 16 commits into from
May 24, 2018
Merged

Conversation

bengourley
Copy link
Contributor

@bengourley bengourley commented May 18, 2018

Goal

This PR adds a new end-to-end test suite using maze-runner. This tool factors out common tasks and assertion utilities that are needed across our notifier libraries. The main goals are:

  • more complete coverage
  • commonality amongst notifier testing
  • facilitate simple addition of scenarios as they arise

Changeset

Added

The entire set of tests, fixtures and support scripts are added in the features directory, which is a cucumber/gherkin convention.

Additionally a Gemfile and Gemfile.lock are added to describe the ruby dependencies.

Tests were added for each of the following cases:

  • an app containing bundled bugsnag-js using webpack
  • a html page linking dist/bugsnag.js
  • a library containing bundled bugsnag-js using rollup
  • Syntax errors
  • Thrown exceptions
  • Malformed URIs
  • Unhandled promise rejections
  • Invoking an undefined function
  • Thrown exception with a malformed stacktrace (TODO)
  • Invoking notify from try/catch
  • Invoking notify from a Promise.catch()
  • Modifying report contents from a per-report callback
  • Setting release stage
  • Setting user info
  • Redacting IP address
  • Global callbacks
  • Disabling autoNotify

Removed

The e2e directory stands to be removed as it is made redundant by the new tests. At the time of writing, coverage would decrease on the following scenarios, so they need to be addressed with maze tests before e2e can sensibly be removed:

Changed

Travis configuration has been updated and currently only runs the maze tests. There is now a build matrix, running a job for each browser to go through all of the end to end scenerios.

  • The existing integration tests browser/**/*.test.js will need to be re-added to the travis build. The test configuration may need to be updated slightly to run this in each browser ci job.
  • The existing unit tests base/**/*.test.js will need to be added re-added to the travis build. This could be done with travis's new build stages because it needn't run for every browser.

Review

For the submitter, initial self-review:

  • Commented on code changes inline explain the reasoning behind the approach
  • Reviewed the test cases added for completeness and possible points for discussion
  • A changelog entry was added for the goal of this pull request
  • Check the scope of the changeset - is everything in the diff required for the pull request?
  • This pull request is ready for:
    • Initial review of the intended approach, not yet feature complete
    • Structural review of the classes, functions, and properties modified
    • Final review

For the pull request reviewer(s), this changeset has been reviewed for:

  • Consistency across platforms for structures or concepts added or modified
  • Consistency between the changeset and the goal stated above
  • Internal consistency with the rest of the library - is there any overlap between existing interfaces and any which have been added?
  • Usage friction - is the proposed change in usage cumbersome or complicated?
  • Performance and complexity - are there any cases of unexpected O(n^3) when iterating, recursing, flat mapping, etc?
  • Concurrency concerns - if components are accessed asynchronously, what issues will arise
  • Thoroughness of added tests and any missing edge cases
  • Idiomatic use of the language

@bengourley bengourley changed the title Maze end to end test suite Add Maze Runner end to end test suite May 18, 2018
@bengourley bengourley requested a review from a team May 18, 2018 16:08
@fractalwrench
Copy link
Contributor

Is there any way we could split this PR up at all into logical sections? I can have a look through, but I'm not confident that I'd see everything that needs catching in a 2.5k+ changeset.

And the test should run in this browser
And I let the test page run for up to 10 seconds
And I wait for 5 seconds
Then I should receive 1 request
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  And the test should run in this browser
  And I let the test page run for up to 10 seconds
  And I wait for 5 seconds
  Then I should receive 1 request

This seems to be a relatively common pattern - would it be worth creating a step which shortens this? On Android/Cocoa we have something along the lines of "When I run the app with the defaults for X"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea.

I was also considering removing the "And the test should run in this browser" from all the tests I know I don't need that check. Lots of the fixtures harcode "YES" for this purpose, which is pretty redundant.

Copy link
Contributor

@kattrali kattrali May 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"should run in this browser" seems like a nice general check, though my one concern with it would be accidentally excluding tests. Though given the implementation, that seems unlikely. Maybe the "YES" could be assumed unless the value is otherwise set?

Feature: beforeSend callbacks

Scenario Outline: modifying report via beforeSend in config
When I navigate to the URL "/before_send/<type>/a.html"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does <type> stand for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a placeholder for this "Scenario Outline". That means that this scenario runs once for every item in the table below it. The <type> placeholder is replaced by a different value from the table each time.

@@ -0,0 +1,19 @@
# copy pasta from https://www.browserstack.com/automate/ruby
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any licensing issues around this? It's probably fine, but IANAL

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doubtful since it came right out of the docs

@bengourley
Copy link
Contributor Author

Is there any way we could split this PR up at all into logical sections?

There are individual commits for each set of features that are tested. There is a view in the PR interface where you can look at one commit at a time, e.g: ac9db8c

@@ -1,2 +1,3 @@
coverage
.nyc_output
features
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also include entries in the .gitignore? i.e. maze_output, others?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe .npmignore inherited rules from .gitignore (so you only need to specify the differences) but I will confirm.

browserstack:
username: bugsnagplatforms1
access_key:
secure: "lB2aZc0HzuinyhSJyP98lzDJTbZsroEOJTrS/flnLLsHb/C096zjhwkWexHnfmNIPaY5SB2FF0G6zcnknlmsXg5TgxQiK7bdyJmkcAetGi+cSKnGaBq7GZXVhbWh++MRnddQDGV6jrSr7aqrWf85ncq3L4//9BTV6uAhDBWu2bo="
before_script:
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this been replaced elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it needs to be readded as per the "changed" section in the PR body (those two sets of tests are what generate the coverage).

<!DOCTYPE html>
<html>
<head>
<script src="dist/a.js"></script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do a/b/c stand for in the JS + HTML files - is there a more descriptive naming scheme that would make sense to use?

setTimeout(function () {
var el = document.getElementById('bugsnag-test-state')
el.textContent = el.innerText = 'DONE'
}, 5000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to extract the 5000 from these scripts to one place, in case we decide to change it in future. Is this the delay required to send a report to Bugsnag?

setTimeout(function () {
var el = document.getElementById('bugsnag-test-state')
el.textContent = el.innerText = 'DONE'
}, 5000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This beforeSend function appears to be the same in a few files. Is there any way of extracting this code to one location?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it duplicated means that each e2e test fixture is self-contained, making it easier to follow and and reduces the chance that a slight change in a helper library could break/invalidate the test result.


root = File.expand_path File.join(__dir__, '..', 'fixtures')
server = WEBrick::HTTPServer.new :Port => ENV['PORT'], :DocumentRoot => root
server.start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this file serve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the static assets in features/fixtures. This expression is resolving the path to that directory in a cross platform way:

File.expand_path File.join(__dir__, '..', 'fixtures')

}
end

Then(/^the request is a valid browser payload for the error reporting API$/) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checks here are good, was there a reason why this needs to be separate from the standard error reporting API step in mazerunner? There may be other notifiers which don't send an API key in the headers.


def current_ip
# Parses the output of `ifconfig` to retreive the host IP for docker to talk to
# Breaks compatability with Windows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any simple way we can maintain compatibility with Windows here?

Then I should receive 1 request
And the request is a valid browser payload for the error reporting API
And the exception matches the "unhandled_syntax" values for the current browser
# TODO: add stacktrace assertions to this type of error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still need to be addressed?

@@ -0,0 +1,48 @@
@release_stage
Feature: Configuring releaseStage and notifyReleaseStages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add scenarios to cover nil/empty releaseStages as well

<head>
<script src="/node_modules/bugsnag-js/dist/bugsnag.min.js"></script>
<script type="text/javascript">
var ENDPOINT = decodeURIComponent(window.location.search.match(/ENDPOINT=(.+)/)[1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've seen window.location.search.match(/ENDPOINT=(.+)/)[1] (and a couple of similar snippets) in multiple places within the fixture scripts. Is it sensible to extract these sort of snippets into separate scripts, or is that a bad idea?

@fractalwrench
Copy link
Contributor

Added a few more inline comments. It'd be good to get someone else to also have a look through this, given the scope of the changes.

kattrali
kattrali previously approved these changes May 22, 2018
Copy link
Contributor

@kattrali kattrali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. I went over the features and helpers in some detail though only sampled the fixtures due to the size. Left a few comments on the existing conversations for thought.

@kattrali kattrali merged commit 242812b into master May 24, 2018
@kattrali kattrali deleted the maze-end-to-end-test-suite branch May 24, 2018 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants