Commit 17d6e564 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '37006-fix-open-details-page-in-new-tab' into 'master'

Fix opening Sentry error details in new tab

See merge request gitlab-org/gitlab!20611
parents d855a7a4 2e6b0caa
...@@ -8,7 +8,6 @@ import { ...@@ -8,7 +8,6 @@ import {
GlTable, GlTable,
GlSearchBoxByClick, GlSearchBoxByClick,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -76,8 +75,8 @@ export default { ...@@ -76,8 +75,8 @@ export default {
this.startPolling(`${this.indexPath}?search_term=${this.errorSearchQuery}`); this.startPolling(`${this.indexPath}?search_term=${this.errorSearchQuery}`);
}, },
trackViewInSentryOptions, trackViewInSentryOptions,
viewDetails(errorId) { getDetailsLink(errorId) {
visitUrl(`error_tracking/${errorId}/details`); return `error_tracking/${errorId}/details`;
}, },
}, },
}; };
...@@ -129,11 +128,7 @@ export default { ...@@ -129,11 +128,7 @@ export default {
</template> </template>
<template slot="error" slot-scope="errors"> <template slot="error" slot-scope="errors">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<gl-link <gl-link class="d-flex text-dark" :href="getDetailsLink(errors.item.id)">
class="d-flex text-dark"
target="_blank"
@click="viewDetails(errors.item.id)"
>
<strong class="text-truncate">{{ errors.item.title.trim() }}</strong> <strong class="text-truncate">{{ errors.item.title.trim() }}</strong>
</gl-link> </gl-link>
<span class="text-secondary text-truncate"> <span class="text-secondary text-truncate">
......
---
title: Fix opening Sentry error details in new tab
merge_request: 20611
author:
type: fixed
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
GlLink, GlLink,
GlSearchBoxByClick, GlSearchBoxByClick,
} from '@gitlab/ui'; } from '@gitlab/ui';
import errorsList from './list_mock.json';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -18,11 +19,17 @@ describe('ErrorTrackingList', () => { ...@@ -18,11 +19,17 @@ describe('ErrorTrackingList', () => {
let wrapper; let wrapper;
let actions; let actions;
const findErrorListTable = () => wrapper.find('table');
const findErrorListRows = () => wrapper.findAll('tbody tr');
const findButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
function mountComponent({ function mountComponent({
errorTrackingEnabled = true, errorTrackingEnabled = true,
userCanEnableErrorTracking = true, userCanEnableErrorTracking = true,
stubs = { stubs = {
'gl-link': GlLink, 'gl-link': GlLink,
'gl-table': GlTable,
}, },
} = {}) { } = {}) {
wrapper = shallowMount(ErrorTrackingList, { wrapper = shallowMount(ErrorTrackingList, {
...@@ -47,7 +54,7 @@ describe('ErrorTrackingList', () => { ...@@ -47,7 +54,7 @@ describe('ErrorTrackingList', () => {
}; };
const state = { const state = {
errors: [], errors: errorsList,
loading: true, loading: true,
}; };
...@@ -75,61 +82,74 @@ describe('ErrorTrackingList', () => { ...@@ -75,61 +82,74 @@ describe('ErrorTrackingList', () => {
}); });
it('shows spinner', () => { it('shows spinner', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBeTruthy(); expect(findLoadingIcon().exists()).toBe(true);
expect(wrapper.find(GlTable).exists()).toBeFalsy(); expect(findErrorListTable().exists()).toBe(false);
}); });
}); });
describe('results', () => { describe('results', () => {
beforeEach(() => { beforeEach(() => {
store.state.list.loading = false; store.state.list.loading = false;
mountComponent(); mountComponent();
}); });
it('shows table', () => { it('shows table', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBeFalsy(); expect(findLoadingIcon().exists()).toBe(false);
expect(wrapper.find(GlTable).exists()).toBeTruthy(); expect(findErrorListTable().exists()).toBe(true);
expect(wrapper.find(GlButton).exists()).toBeTruthy(); expect(findButton().exists()).toBe(true);
});
it('shows list of errors in a table', () => {
expect(findErrorListRows().length).toEqual(store.state.list.errors.length);
});
it('each error in a list should have a link to the error page', () => {
const errorTitle = wrapper.findAll('tbody tr a');
errorTitle.wrappers.forEach((_, index) => {
expect(errorTitle.at(index).attributes('href')).toEqual(
expect.stringMatching(/error_tracking\/\d+\/details$/),
);
});
}); });
describe('filtering', () => { describe('filtering', () => {
const findSearchBox = () => wrapper.find(GlSearchBoxByClick);
it('shows search box', () => { it('shows search box', () => {
expect(wrapper.find(GlSearchBoxByClick).exists()).toBeTruthy(); expect(findSearchBox().exists()).toBe(true);
}); });
it('makes network request on submit', () => { it('makes network request on submit', () => {
expect(actions.startPolling).toHaveBeenCalledTimes(1); expect(actions.startPolling).toHaveBeenCalledTimes(1);
findSearchBox().vm.$emit('submit');
wrapper.find(GlSearchBoxByClick).vm.$emit('submit');
expect(actions.startPolling).toHaveBeenCalledTimes(2); expect(actions.startPolling).toHaveBeenCalledTimes(2);
}); });
}); });
}); });
describe('no results', () => { describe('no results', () => {
const findRefreshLink = () => wrapper.find('.js-try-again');
beforeEach(() => { beforeEach(() => {
store.state.list.loading = false; store.state.list.loading = false;
store.state.list.errors = [];
mountComponent(); mountComponent();
}); });
it('shows empty table', () => { it('shows empty table', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBeFalsy(); expect(findLoadingIcon().exists()).toBe(false);
expect(wrapper.find(GlTable).exists()).toBeTruthy(); expect(findErrorListRows().length).toEqual(1);
expect(wrapper.find(GlButton).exists()).toBeTruthy(); expect(findButton().exists()).toBe(true);
}); });
it('shows a message prompting to refresh', () => { it('shows a message prompting to refresh', () => {
const refreshLink = wrapper.vm.$refs.empty.querySelector('a'); expect(findRefreshLink().text()).toContain('Check again');
expect(refreshLink.textContent.trim()).toContain('Check again');
}); });
it('restarts polling', () => { it('restarts polling', () => {
wrapper.find('.js-try-again').trigger('click'); findRefreshLink().trigger('click');
expect(actions.restartPolling).toHaveBeenCalled(); expect(actions.restartPolling).toHaveBeenCalled();
}); });
}); });
...@@ -140,10 +160,10 @@ describe('ErrorTrackingList', () => { ...@@ -140,10 +160,10 @@ describe('ErrorTrackingList', () => {
}); });
it('shows empty state', () => { it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBeTruthy(); expect(wrapper.find(GlEmptyState).exists()).toBe(true);
expect(wrapper.find(GlLoadingIcon).exists()).toBeFalsy(); expect(findLoadingIcon().exists()).toBe(false);
expect(wrapper.find(GlTable).exists()).toBeFalsy(); expect(findErrorListTable().exists()).toBe(false);
expect(wrapper.find(GlButton).exists()).toBeFalsy(); expect(findButton().exists()).toBe(false);
}); });
}); });
......
[
{
"id": "1",
"title": "PG::ConnectionBad: FATAL",
"type": "error",
"userCount": 0,
"count": "52",
"firstSeen": "2019-05-30T07:21:46Z",
"lastSeen": "2019-11-06T03:21:39Z"
},
{
"id": "2",
"title": "ActiveRecord::StatementInvalid",
"type": "error",
"userCount": 0,
"count": "12",
"firstSeen": "2019-10-19T03:53:56Z",
"lastSeen": "2019-11-05T03:51:54Z"
},
{
"id": "3",
"title": "Command has failed",
"type": "default",
"userCount": 0,
"count": "275",
"firstSeen": "2019-02-12T07:22:36Z",
"lastSeen": "2019-10-22T03:20:48Z"
}
]
\ No newline at end of file
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