Skip to content

Commit

Permalink
feat(quantic): QuanticResultCopyToClipboard component created (#2558)
Browse files Browse the repository at this point in the history
* SFINT-4476 QuanticResultAction component created

* SFINT-4476 QuanticResultAction improved

* SFINT-4476 QuanticResultActionBar component created

* SFINT-4476 improvments to the QuanticResult action components

* SFINT-4476 typo fixed

* SFINT-4476 tests improved

* SFINT-4476 QuanticResultAction component improved

* SFINT-4481 QuanticResultCopyToClipboard component created

* SFINT-4476 QuanticResultAction and QuanticResultActionBar improved

* SFINT-4476 typos fixed

* Update packages/quantic/force-app/main/default/lwc/quanticResultAction/quanticResultAction.js

* Update packages/quantic/force-app/main/default/lwc/quanticResultAction/quanticResultAction.js

* SFINT-4476 typing added

* SFINT-4476 few improvements added

* SFINT-4476 PR feedbacks applied

* SFINT-4476 margin added

* SFINT-4481 copy to clipboard analytics logged

* Update packages/quantic/force-app/main/default/lwc/quanticResultAction/__tests__/quanticResultAction.test.js

Co-authored-by: Luc Bergeron <[email protected]>

* SFINT-4476 new selectedIconName property added

* SFINT-4481 e2e tests for QuanticResultCopyToClipboard setup

* e2e tests setup

* SFINT-4481 temp folder deleted

* SFINT-4481 comments added

* SFINT-4481 e2e for QuanticResultCopyToClipboard improved

* SFINT-4481 logCopyToClipboard added

* SFINT-4481 imroved e2e tests for copy to clipboard

* Update packages/quantic/force-app/main/default/lwc/quanticQueryError/quanticQueryError.js

* SFINT-4481 improvments applied

* SFINT-4481 unused import deleted

* Update packages/quantic/force-app/main/default/lwc/quanticResultCopyToClipboard/quanticResultCopyToClipboard.js

Co-authored-by: Nathan Lafrance-Berger <[email protected]>

* SFINT-4481 feedbacks from PR applied

* SFINT-4481 comments updated

* SFINT-4481 deprecated copyToClipboard fallback removed

Co-authored-by: Luc Bergeron <[email protected]>
Co-authored-by: Nathan Lafrance-Berger <[email protected]>
  • Loading branch information
3 people authored Dec 9, 2022
1 parent 8463bc6 commit ddedd97
Show file tree
Hide file tree
Showing 18 changed files with 551 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
CopyToClipboardSelector,
CopyToClipboardSelectors,
} from './copy-to-clipboard-selectors';

function copyToClipboardActions(selector: CopyToClipboardSelector) {
return {
clickCopyToClipboardButton: () =>
selector
.copyToClipboardButton()
.click()
.logAction('When clicking on the copy to clipboard button'),
};
}

export const CopyToClipboardActions = {
...copyToClipboardActions(CopyToClipboardSelectors),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {InterceptAliases} from '../../../page-objects/search';
import {
CopyToClipboardSelector,
CopyToClipboardSelectors,
} from './copy-to-clipboard-selectors';

function copyToClipboardExpectations(selector: CopyToClipboardSelector) {
return {
displayCopyToClipboardButton: (display: boolean) => {
selector
.copyToClipboardButton()
.should(display ? 'exist' : 'not.exist')
.log('should display the copy to clipboard button');
},

displayCopyToClipboardTooltip: (label: string) => {
selector
.copyToClipboardTooltip()
.contains(label)
.log('should display the copy to clipboard tooltip');
},

logCopyToClipboard: (result: {
title: string;
clickUri: string;
raw: {urihash: string};
}) => {
cy.wait(InterceptAliases.UA.CopyToClipboard)
.then((interception) => {
const analyticsBody = interception.request.body;
expect(analyticsBody).to.have.property('documentTitle', result.title);
expect(analyticsBody).to.have.property(
'documentUri',
result.clickUri
);
expect(analyticsBody).to.have.property(
'documentUrl',
result.clickUri
);
expect(analyticsBody).to.have.property(
'documentUriHash',
result.raw.urihash
);
expect(analyticsBody).to.have.property('documentPosition', 1);
})
.logDetail("should log the 'copyToClipboard' UA event");
},
};
}

export const CopyToClipboardExpectations = {
...copyToClipboardExpectations(CopyToClipboardSelectors),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ComponentSelector, CypressSelector} from '../../common-selectors';

export const copyToClpboardComponent = 'c-quantic-result-copy-to-clipboard';

export interface CopyToClipboardSelector extends ComponentSelector {
copyToClipboardButton: () => CypressSelector;
copyToClipboardTooltip: () => CypressSelector;
}

export const CopyToClipboardSelectors: CopyToClipboardSelector = {
get: () => cy.get(copyToClpboardComponent),

copyToClipboardButton: () =>
CopyToClipboardSelectors.get().find('lightning-button-icon-stateful'),
copyToClipboardTooltip: () =>
CopyToClipboardSelectors.get().find('.slds-popover'),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {performSearch} from '../../../page-objects/actions/action-perform-search';
import {configure} from '../../../page-objects/configurator';
import {interceptSearch} from '../../../page-objects/search';
import {InsightInterfaceExpectations as InsightInterfaceExpect} from '../../../page-objects/use-case';
import {CopyToClipboardActions as Actions} from './copy-to-clipboard-actions';
import {CopyToClipboardExpectations as Expect} from './copy-to-clipboard-expectations';

interface copyToClipboardOptions {
label: string;
successLabel: string;
textTemplate: string;
}

const testResult = {
clickUri: 'https://test.com',
Excerpt: 'Test excerpt',
title: 'Test result',
raw: {
urihash: 'Test uri hash',
objecttype: 'Test',
source: 'Test source',
date: 1669504751000,
},
};

const defaultLabel = 'Copy';
const defaultSuccessLabel = 'Copied!';
const customLabel = 'Copy to clipboard';
const customSuccessLabel = 'Copied to clipboard!';
const customTextTemplate = '${raw.source} : ${clickUri}';

// access to the clipboard reliably works in Electron browser
// in other browsers, there are popups asking for permission
// thus we should only run these tests in Electron
describe('quantic-result-copy-to-clipboard', {browser: 'electron'}, () => {
const pageUrl = 's/quantic-result-copy-to-clipboard';

function visitCopyToClipboard(options: Partial<copyToClipboardOptions>) {
interceptSearch();
cy.visit(pageUrl);
configure(options);
InsightInterfaceExpect.isInitialized();
performSearch();
}

describe('with the default options', () => {
it('should correctly display the copy to clipboard button', () => {
visitCopyToClipboard({});

Expect.displayCopyToClipboardButton(true);
Expect.displayCopyToClipboardTooltip(defaultLabel);
});

it('should correctly copy the result to clipboard', () => {
visitCopyToClipboard({});

Expect.displayCopyToClipboardButton(true);
Actions.clickCopyToClipboardButton();
Expect.displayCopyToClipboardTooltip(defaultSuccessLabel);
Expect.logCopyToClipboard(testResult);

cy.window()
.its('navigator.clipboard')
.invoke('readText')
.should('equal', `${testResult.title}\n${testResult.clickUri}`);
});
});

describe('with custom options', () => {
it('should correctly display the copy to clipboard button', () => {
visitCopyToClipboard({
label: customLabel,
});

Expect.displayCopyToClipboardButton(true);
Expect.displayCopyToClipboardTooltip(customLabel);
});

it('should correctly copy the result to clipboard', () => {
visitCopyToClipboard({
successLabel: customSuccessLabel,
textTemplate: customTextTemplate,
});

Expect.displayCopyToClipboardButton(true);
Actions.clickCopyToClipboardButton();
Expect.displayCopyToClipboardTooltip(customSuccessLabel);
Expect.logCopyToClipboard(testResult);

cy.window()
.its('navigator.clipboard')
.invoke('readText')
.should('equal', `${testResult.raw.source} : ${testResult.clickUri}`);
});
});
});
1 change: 1 addition & 0 deletions packages/quantic/cypress/page-objects/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const InterceptAliases = {
DocumentOpen: uaAlias('documentOpen'),
DocumentQuickview: uaAlias('documentQuickview'),
SearchFromLink: uaAlias('searchFromLink'),
CopyToClipboard: uaAlias('copyToClipboard'),
},
QuerySuggestions: '@coveoQuerySuggest',
Search: '@coveoSearch',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<c-example-layout title={pageTitle} description={pageDescription} show-preview={isConfigured}>
<div slot="configuration">
<c-configurator options={options} ontryitnow={handleTryItNow}>
<c-action-perform-search slot="actions" disabled={notConfigured} engine-id={engineId}></c-action-perform-search>
</c-configurator>
</div>

<c-example-use-case slot="preview" use-case="insight" engine-id={engineId}>
<c-quantic-result-copy-to-clipboard engine-id={engineId} result={testResult} label={config.label}
success-label={config.successLabel} text-template={config.textTemplate}></c-quantic-result-copy-to-clipboard>
<c-quantic-result engine-id={engineId} result={testResult} result-templates-manager={resultTemplateManager}>
</c-quantic-result>
</c-example-use-case>
</c-example-layout>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {LightningElement, api, track} from 'lwc';

export default class ExampleQuanticResultCopyToClipboard extends LightningElement {
@api engineId = 'quantic-result-copy-to-clipboard-engine';
@track config = {};
isConfigured = false;

pageTitle = 'Quantic Result Copy To Clipboard';
pageDescription =
'The QuanticResultCopyToClipboard component allows the end user to copy a result to clipboard.';
options = [
{
attribute: 'label',
label: 'Label',
description: 'The label to be displayed in the tooltip of the button.',
defaultValue: 'Copy',
},
{
attribute: 'successLabel',
label: 'Success Label',
description:
'The label to be displayed in the tooltip of the button when the action is successful.',
defaultValue: 'Copied!',
},
{
attribute: 'textTemplate',
label: 'Text Template',
description:
'The template used to generate the text to copy to clipboard.',
defaultValue: '${title}\n${clickUri}',
},
];

testResult = {
clickUri: 'https://test.com',
excerpt: 'Test excerpt',
title: 'Test result',
uniqueId: 'Test unique id',
uri: 'https://test.com',
raw: {
urihash: 'Test uri hash',
permanentid: 'Test permanent id',
objecttype: 'Test',
source: 'Test source',
date: 1669504751000,
},
};

resultTemplateManager = {
selectTemplate: () => null,
};

handleTryItNow(evt) {
this.config = evt.detail;
this.isConfigured = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>
Original file line number Diff line number Diff line change
Expand Up @@ -889,4 +889,18 @@
<protected>false</protected>
<shortDescription>No filters available in the current tab</shortDescription>
</labels>
<labels>
<fullName>quantic_Copy</fullName>
<value>Copy</value>
<language>en_US</language>
<protected>false</protected>
<shortDescription>Copy</shortDescription>
</labels>
<labels>
<fullName>quantic_Copied</fullName>
<value>Copied!</value>
<language>en_US</language>
<protected>false</protected>
<shortDescription>Copied!</shortDescription>
</labels>
</CustomLabels>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LightningElement, api, track } from 'lwc';
import { registerComponentForInit, initializeWithHeadless, getHeadlessBundle } from 'c/quanticHeadlessLoader';
import { AriaLiveRegion, I18nUtils } from 'c/quanticUtils';
import { copyToClipboard } from 'c/quanticUtils';

import coveoOnlineHelpLink from '@salesforce/label/c.quantic_CoveoOnlineHelpLink';
import moreInformation from '@salesforce/label/c.quantic_MoreInformation';
Expand Down Expand Up @@ -36,7 +37,7 @@ export default class QuanticQueryError extends LightningElement {
/** @type {Boolean} */
@track hasError;
/** @type {string} */
@track error
@track error;

/** @type {QueryError} */
queryError;
Expand Down Expand Up @@ -111,27 +112,10 @@ export default class QuanticQueryError extends LightningElement {

async handleCopyToClipboard() {
const text = this.template.querySelector('code').textContent;
if (navigator?.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(text);
} catch (err) {
console.error('Copy to clipboard failed.', text, err);
this.copyToClipboardFallback(text);
}
} else {
this.copyToClipboardFallback(text);
}
}
/**
* @param {string} text
*/
copyToClipboardFallback(text) {
const el = document.createElement('textarea');
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);

copyToClipboard(text).catch((err) => {
console.error('Copy to clipboard failed.', text, err);
});
}

get checkForMoreLabel() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<c-quantic-result-action event-name='quantic__copytoclipboard' result={result} icon-name='utility:copy' label={displayedLabel}></c-quantic-result-action>
</template>
Loading

0 comments on commit ddedd97

Please sign in to comment.