Commit c6e25fa9 authored by Allison Browne's avatar Allison Browne Committed by Rémy Coutable

Add feature specs for error tracking

Add feature specs covering the error tracking index
and the error tracking show page. Inculde expandable
stack traces in the feature spec.
parent dcdb7ce3
......@@ -3,7 +3,7 @@
FactoryBot.define do
factory :project_error_tracking_setting, class: 'ErrorTracking::ProjectErrorTrackingSetting' do
project
api_url { 'https://gitlab.com/api/0/projects/sentry-org/sentry-project' }
api_url { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' }
enabled { true }
token { 'access_token_123' }
project_name { 'Sentry Project' }
......
# frozen_string_literal: true
require 'spec_helper'
describe 'View error details page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
context 'with current user as project owner' do
before do
sign_in(project.owner)
visit details_project_error_tracking_index_path(project, issue_id: issue_id)
end
it_behaves_like 'error tracking show page'
end
context 'with current user as project guest' do
let_it_be(:user) { create(:user) }
before do
project.add_guest(user)
sign_in(user)
visit details_project_error_tracking_index_path(project, issue_id: issue_id)
end
it 'renders not found' do
expect(page).to have_content('Page Not Found')
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'View error index page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
let_it_be(:issues_response) { JSON.parse(issues_response_body) }
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
before do
stub_request(:get, issues_api_url).with(
headers: { 'Authorization' => 'Bearer access_token_123' }
).to_return(status: 200, body: issues_response_body, headers: { 'Content-Type' => 'application/json' })
end
context 'with current user as project owner' do
before do
sign_in(project.owner)
visit project_error_tracking_index_path(project)
end
it_behaves_like 'error tracking index page'
end
# A bug caused the detail link to be broken for all users but the project owner
context 'with current user as project maintainer' do
let_it_be(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
visit project_error_tracking_index_path(project)
end
it_behaves_like 'error tracking index page'
end
context 'with error tracking settings disabled' do
before do
project_error_tracking_settings.update(enabled: false)
sign_in(project.owner)
visit project_error_tracking_index_path(project)
end
it 'renders call to action' do
expect(page).to have_content('Enable error tracking')
end
end
context 'with current user as project guest' do
let_it_be(:user) { create(:user) }
before do
project.add_guest(user)
sign_in(user)
visit project_error_tracking_index_path(project)
end
it 'renders not found' do
expect(page).to have_content('Page Not Found')
end
end
end
......@@ -38,7 +38,7 @@
},
"firstSeen": "2018-11-06T21:19:55Z",
"hasSeen": false,
"id": "503504",
"id": "11",
"isBookmarked": false,
"isPublic": false,
"isSubscribed": true,
......@@ -72,232 +72,64 @@
"shortId": "PUMP-STATION-1",
"stats": {
"24h": [
[
1541451600.0,
557
],
[
1541455200.0,
473
],
[
1541458800.0,
914
],
[
1541462400.0,
991
],
[
1541466000.0,
925
],
[
1541469600.0,
881
],
[
1541473200.0,
182
],
[
1541476800.0,
490
],
[
1541480400.0,
820
],
[
1541484000.0,
322
],
[
1541487600.0,
836
],
[
1541491200.0,
565
],
[
1541494800.0,
758
],
[
1541498400.0,
880
],
[
1541502000.0,
677
],
[
1541505600.0,
381
],
[
1541509200.0,
814
],
[
1541512800.0,
329
],
[
1541516400.0,
446
],
[
1541520000.0,
731
],
[
1541523600.0,
111
],
[
1541527200.0,
926
],
[
1541530800.0,
772
],
[
1541534400.0,
400
],
[
1541538000.0,
943
]
[1541451600.0, 557],
[1541455200.0, 473],
[1541458800.0, 914],
[1541462400.0, 991],
[1541466000.0, 925],
[1541469600.0, 881],
[1541473200.0, 182],
[1541476800.0, 490],
[1541480400.0, 820],
[1541484000.0, 322],
[1541487600.0, 836],
[1541491200.0, 565],
[1541494800.0, 758],
[1541498400.0, 880],
[1541502000.0, 677],
[1541505600.0, 381],
[1541509200.0, 814],
[1541512800.0, 329],
[1541516400.0, 446],
[1541520000.0, 731],
[1541523600.0, 111],
[1541527200.0, 926],
[1541530800.0, 772],
[1541534400.0, 400],
[1541538000.0, 943]
],
"30d": [
[
1538870400.0,
565
],
[
1538956800.0,
12862
],
[
1539043200.0,
15617
],
[
1539129600.0,
10809
],
[
1539216000.0,
15065
],
[
1539302400.0,
12927
],
[
1539388800.0,
12994
],
[
1539475200.0,
13139
],
[
1539561600.0,
11838
],
[
1539648000.0,
12088
],
[
1539734400.0,
12338
],
[
1539820800.0,
12768
],
[
1539907200.0,
12816
],
[
1539993600.0,
15356
],
[
1540080000.0,
10910
],
[
1540166400.0,
12306
],
[
1540252800.0,
12912
],
[
1540339200.0,
14700
],
[
1540425600.0,
11890
],
[
1540512000.0,
11684
],
[
1540598400.0,
13510
],
[
1540684800.0,
12625
],
[
1540771200.0,
12811
],
[
1540857600.0,
13180
],
[
1540944000.0,
14651
],
[
1541030400.0,
14161
],
[
1541116800.0,
12612
],
[
1541203200.0,
14316
],
[
1541289600.0,
14742
],
[
1541376000.0,
12505
],
[
1541462400.0,
14180
]
[1538870400.0, 565],
[1538956800.0, 12862],
[1539043200.0, 15617],
[1539129600.0, 10809],
[1539216000.0, 15065],
[1539302400.0, 12927],
[1539388800.0, 12994],
[1539475200.0, 13139],
[1539561600.0, 11838],
[1539648000.0, 12088],
[1539734400.0, 12338],
[1539820800.0, 12768],
[1539907200.0, 12816],
[1539993600.0, 15356],
[1540080000.0, 10910],
[1540166400.0, 12306],
[1540252800.0, 12912],
[1540339200.0, 14700],
[1540425600.0, 11890],
[1540512000.0, 11684],
[1540598400.0, 13510],
[1540684800.0, 12625],
[1540771200.0, 12811],
[1540857600.0, 13180],
[1540944000.0, 14651],
[1541030400.0, 14161],
[1541116800.0, 12612],
[1541203200.0, 14316],
[1541289600.0, 14742],
[1541376000.0, 12505],
[1541462400.0, 14180]
]
},
"status": "unresolved",
......
......@@ -8,7 +8,7 @@ describe Sentry::Client::Issue do
let(:token) { 'test-token' }
let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0' }
let(:client) { Sentry::Client.new(sentry_url, token) }
let(:issue_id) { 503504 }
let(:issue_id) { 11 }
describe '#list_issues' do
shared_examples 'issues have correct return type' do |klass|
......@@ -243,7 +243,7 @@ describe Sentry::Client::Issue do
end
it 'has a correct external URL' do
expect(subject.external_url).to eq('https://sentrytest.gitlab.com/api/0/issues/503504')
expect(subject.external_url).to eq('https://sentrytest.gitlab.com/api/0/issues/11')
end
it 'issue has a correct external base url' do
......
# frozen_string_literal: true
shared_context 'sentry error tracking context feature' do
include ReactiveCachingHelpers
let_it_be(:project) { create(:project) }
let_it_be(:project_error_tracking_settings) { create(:project_error_tracking_setting, project: project) }
let_it_be(:issue_response_body) { fixture_file('sentry/issue_sample_response.json') }
let_it_be(:issue_response) { JSON.parse(issue_response_body) }
let_it_be(:event_response_body) { fixture_file('sentry/issue_latest_event_sample_response.json') }
let_it_be(:event_response) { JSON.parse(event_response_body) }
let(:sentry_api_urls) { Sentry::ApiUrls.new(project_error_tracking_settings.api_url) }
let(:issue_id) { issue_response['id'] }
before do
request_headers = { 'Authorization' => 'Bearer access_token_123', 'Content-Type' => 'application/json' }
response_headers = { 'Content-Type' => 'application/json' }
issue_url = sentry_api_urls.issue_url(issue_id).to_s
stub_request(:get, issue_url)
.with(headers: request_headers)
.to_return(status: 200, body: issue_response_body, headers: response_headers)
event_url = sentry_api_urls.issue_latest_event_url(issue_id).to_s
stub_request(:get, event_url)
.with(headers: request_headers)
.to_return(status: 200, body: event_response_body, headers: response_headers)
end
end
# frozen_string_literal: true
shared_examples 'error tracking index page' do
it 'renders the error index page' do
within('div.js-title-container') do
expect(page).to have_content(project.namespace.name)
expect(page).to have_content(project.name)
end
within('div.error-list') do
expect(page).to have_content('Error')
expect(page).to have_content('Events')
expect(page).to have_content('Users')
expect(page).to have_content('Last Seen')
end
end
it 'loads the error show page on click' do
click_on issues_response[0]['title']
wait_for_requests
expect(page).to have_content('Error Details')
end
it 'renders the error index data' do
Timecop.freeze(2020, 01, 01, 12, 0, 0) do
within('div.error-list') do
expect(page).to have_content(issues_response[0]['title'])
expect(page).to have_content(issues_response[0]['count'].to_s)
expect(page).to have_content(issues_response[0]['last_seen'])
expect(page).to have_content('1 year ago')
end
end
end
end
shared_examples 'expanded stack trace context' do |selected_line: nil, expected_line: 1|
it 'expands the stack trace context' do
within('div.stacktrace') do
find("div.file-holder:nth-child(#{selected_line}) svg.ic-chevron-right").click if selected_line
expanded_line = find("div.file-holder:nth-child(#{expected_line})")
expect(expanded_line).to have_css('svg.ic-chevron-down')
event_response['entries'][0]['data']['values'][0]['stacktrace']['frames'][-expected_line]['context'].each do |context|
expect(page).to have_content(context[0])
end
end
end
end
shared_examples 'error tracking show page' do
it 'renders the error details' do
release_short_version = issue_response['firstRelease']['shortVersion']
Timecop.freeze(2020, 01, 01, 12, 0, 0) do
expect(page).to have_content('1 month ago by raven.scripts.runner in main')
expect(page).to have_content(issue_response['metadata']['title'])
expect(page).to have_content('level: error')
expect(page).to have_content('Error Details')
expect(page).to have_content('GitLab Issue: https://gitlab.com/gitlab-org/gitlab/issues/1')
expect(page).to have_content("Sentry event: https://sentrytest.gitlab.com/sentry-org/sentry-project/issues/#{issue_id}")
expect(page).to have_content("First seen: 1 year ago (2018-11-06 9:19:55PM UTC) Release: #{release_short_version}")
expect(page).to have_content('Events: 1')
expect(page).to have_content('Users: 0')
end
end
it 'renders the stack trace heading' do
expect(page).to have_content('Stack trace')
end
it 'renders the stack trace' do
event_response['entries'][0]['data']['values'][0]['stacktrace']['frames'].each do |frame|
expect(frame['filename']).not_to be_nil
expect(page).to have_content(frame['filename'])
end
end
# The first line is expanded by default if no line is selected
it_behaves_like 'expanded stack trace context', selected_line: nil, expected_line: 1
it_behaves_like 'expanded stack trace context', selected_line: 8, expected_line: 8
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment