From f07af5a45d883cb629d4d0ef7e953cf8444619d3 Mon Sep 17 00:00:00 2001 From: jonasongg <120372506+jonasongg@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:30:32 +0800 Subject: [PATCH 1/2] [#2130] Add highlight and scroll to group (#2131) Add highlight and scroll to group It can be useful to have a way to send a RepoSense link that automatically scrolls to and highlights the group that the sender thinks the recipient should pay attention to, saving them time to find the repo in question. Let's add this functionality to add convenience when sending around RepoSense reports. --- .../chartView_scrollToActiveRepo.cy.js | 62 +++++++++++++++++++ frontend/src/components/c-summary-charts.vue | 21 ++++++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js diff --git a/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js b/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js new file mode 100644 index 0000000000..97afc7b1ea --- /dev/null +++ b/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js @@ -0,0 +1,62 @@ +describe('scroll to active repo', () => { + // need to set scrollBehavior to false because the default behavior is to scroll the element into view + it('selecting a visible repo should not scroll', { scrollBehavior: false }, () => { + // close the error message box + cy.get('.error-message-box') + .should('be.visible'); + + cy.get('#summary-wrapper > #summary > .error-message-box > .error-message-box__close-button') + .click(); + + cy.get('.error-message-box') + .should('not.be.visible'); + + cy.get('.icon-button.fa-code') + .should('exist') + .first(); + + let scrollTopOriginal = 0; + cy.get('#summary-wrapper') + .first() + .then(($el) => { + scrollTopOriginal = $el.prop('scrollTop'); + }); + + cy.get('.icon-button.fa-code') + .should('exist') + .first() + .click(); + + cy.get('#summary-wrapper') + .first() + .then(($el) => { + const scrollTop = $el.prop('scrollTop'); + expect(scrollTop).to.equal(scrollTopOriginal); + }); + }); + + it('selecting a non-visible repo should scroll', () => { + cy.get('.icon-button.fa-code') + .should('exist') + .last() + .click(); + + cy.get('#summary-wrapper') + .first() + .then(($el) => { + const scrollTop = $el.prop('scrollTop'); + expect(scrollTop).to.not.equal(0); + }); + + cy.url() + .should('contain', 'tabAuthor=yong24s') + .should('contain', 'tabRepo=reposense%2FRepoSense%5Bcypress%5D'); + + cy.reload(); + + cy.get('.icon-button.fa-code') + .should('exist') + .last() + .should('be.visible'); + }); +}); diff --git a/frontend/src/components/c-summary-charts.vue b/frontend/src/components/c-summary-charts.vue index e017ec6045..7ebe313ddf 100644 --- a/frontend/src/components/c-summary-charts.vue +++ b/frontend/src/components/c-summary-charts.vue @@ -153,7 +153,8 @@ .summary-chart( v-for="(user, j) in getRepo(repo)", v-bind:style="isChartGroupWidgetMode && j === getRepo(repo).length - 1 ? {'marginBottom': 0} : {}", - v-bind:ref="'summary-chart-' + j" + v-bind:ref="'summary-chart-' + j", + v-bind:id="user.name === activeUser && user.repoName === activeRepo ? 'selectedChart' : null" ) .summary-chart__title( v-if="!isGroupMerged(getGroupName(repo))", @@ -428,6 +429,15 @@ export default defineComponent({ this.removeSelectedTab(); } }, + + // watching so highlighted only when summary charts are rendered + filteredRepos() { + this.$nextTick(() => { + if (this.activeRepo !== null && this.activeUser !== null) { + this.scrollToActiveRepo(); + } + }); + }, }, created(): void { this.retrieveSelectedTabHash(); @@ -829,6 +839,8 @@ export default defineComponent({ this.activeTabType = tabType; window.encodeHash(); + + this.$nextTick(() => this.scrollToActiveRepo()); }, removeSelectedTab(): void { @@ -881,6 +893,13 @@ export default defineComponent({ return totalContribution / totalCommits; }, + + scrollToActiveRepo(): void { + const chart = document.getElementById('selectedChart'); + if (chart) { + chart.scrollIntoView({ block: 'nearest' }); + } + }, }, }); From eb138361cfe928eec29327cf63ac965911a94e29 Mon Sep 17 00:00:00 2001 From: Ryan Poon <96387349+sopa301@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:38:39 +0800 Subject: [PATCH 2/2] [#2136] Add Tests for Segment CSS (#2137) Write Tests for Code Highlighting for Segment A regression has occurred during refactoring of the Segment component. It would be good to write tests to catch regressions if it happens again for this component. Let's write tests to catch further regressions of the same nature. --- .../codeView/codeView_codeHighlighting.cy.js | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 frontend/cypress/tests/codeView/codeView_codeHighlighting.cy.js diff --git a/frontend/cypress/tests/codeView/codeView_codeHighlighting.cy.js b/frontend/cypress/tests/codeView/codeView_codeHighlighting.cy.js new file mode 100644 index 0000000000..adbd9c338c --- /dev/null +++ b/frontend/cypress/tests/codeView/codeView_codeHighlighting.cy.js @@ -0,0 +1,67 @@ +// Assumes: RepoSense repo from 03/05/2018 to current date +describe('code highlighting works properly', () => { + it('should highlight code when there is a single author', () => { + // open the code panel + cy.get('.icon-button.fa-code') + .should('exist') + .first() + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + + cy.get('.hljs-comment').contains('* Represents a Git Author.') + .parent() // .line-content + .parent() // .code + .should('have.css', 'background-color', 'rgb(230, 255, 237)'); // #e6ffed + }); + + it('should highlight code when multiple authors are merged in a repo group', () => { + cy.get('div.mui-select.grouping > select:visible') + .select('groupByRepos'); + + cy.get('#summary label.merge-group > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + // open the code panel + cy.get('.icon-button.fa-code') + .should('exist') + .first() + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + + cy.get('.hljs-comment').contains('* MUI Colors module') // eugenepeh + .parent() // .line-content + .parent() // .code + .should('have.css', 'background-color', 'rgba(30, 144, 255, 0.19)') // #1e90ff, transparencyValue 30 + .then((firstAuthorColor) => { + // eslint-disable-next-line quotes + cy.get('.line-content').contains("'red': (") // jamessspanggg + .parent() // .code + // #f08080, transparencyValue 30 + .should('have.css', 'background-color', 'rgba(240, 128, 128, 0.19)') + .and('not.eq', firstAuthorColor); + }); + }); + + it('should not highlight non-attributed lines', () => { + // open the code panel + cy.get('.icon-button.fa-code') + .should('exist') + .first() + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + + cy.get('.hljs-title').contains('Author') + .parent() // .hljs-class + .parent() // .line-content + .parent() // .code + .should('have.css', 'background-color', 'rgb(255, 255, 255)'); // #ffffff + }); +});