Skip to content

Commit

Permalink
[Release] Stage to Main (#2910)
Browse files Browse the repository at this point in the history
  • Loading branch information
milo-pr-merge[bot] authored Sep 24, 2024
2 parents 132d69f + b600045 commit 7c2d611
Show file tree
Hide file tree
Showing 58 changed files with 1,748 additions and 534 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/label-zero-impact.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ const zeroImpactDirs = [
'.vscode',
'.test',
'.browserslistrc',
'libs/mep',
'.gitignore',
'.eslintrc.js',
'CODEOWNERS',
'web-test-runner.config.mjs',
'LICENSE',
'codecov.yaml',
'.gitignore',
'package.json',
'package-lock.json',
'test',
'libs/mep',
'nala'
];
const zeroImpactLabel = 'zero-impact';

Expand Down
1 change: 1 addition & 0 deletions .hlxignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ LICENSE
web-test-runner.config.mjs
codecov.yaml
libs/features/mas/*
!libs/features/mas/docs
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ https://feat-branch--project--owner.hlx.page/?milolibs=local (feature code, stag
```

## Testing
### Unit Testing
```sh
npm run test
```
Expand All @@ -69,3 +70,45 @@ npm run test:watch
### Coverage
`npm run test:watch` can give misleading coverage reports. Use `npm run test` for accurate coverage reporting.

### Nala E2E UI Testing
-----

#### 1. Running Nala Tests
Nala tests are run using the `npm run nala <env> [options]` command:

```sh
npm run nala <env> [options]
```
```sh
# env: [local | libs | branch | stage | etc ] default: local

# options:
- browser=<chrome|firefox|webkit> # Browser to use (default: chrome)
- device=<desktop|mobile> # Device (default: desktop)
- test=<.test.js> # Specific test file to run (runs all tests in the file)
- -g, --g=<@tag> # Tag to filter tests by annotations ex: @test1 @accordion @marquee
- mode=<headless|ui|debug|headed> # Mode (default: headless)
- config=<config-file> # Configuration file (default: Playwright default)
- project=<project-name> # Project configuration (default: milo-live-chromium)
- milolibs=<local|prod|feature|any|> # Milolibs?=<env>

```
#### 2. Nala Help Command:
To view examples of how to use Nala commands with various options, you can run
```sh
npm run nala help
```

#### ⚠️ Important Note
- **Debug and UI Mode Caution**: When using `debug` or `ui` mode, it is recommended to run only a single test using annotations (e.g., `@test1`). Running multiple tests in these modes (e.g., `npm run nala local mode=debug` or `mode=ui`) will launch a separate browser or debugger window for each test, which can quickly become resource-intensive and challenging to manage.

- **Tip**: To effectively watch or debug, focus on one test at a time to avoid opening excessive browser instances or debugger windows.

#### 3. Nala Documentation
For detailed guides and documentation on Nala, please visit the [Nala GitHub Wiki](https://github.com/adobecom/milo/wiki/Nala#nala-introduction).






17 changes: 11 additions & 6 deletions libs/blocks/bulk-publish-v2/components/bulk-publisher.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import './job-process.js';
import { LitElement, html } from '../../../deps/lit-all.min.js';
import { getSheet } from '../../../../tools/utils/utils.js';
import { authenticate, startJob } from '../services.js';
import { authenticate, getPublishable, startJob } from '../services.js';
import { getConfig } from '../../../utils/utils.js';
import {
delay,
Expand Down Expand Up @@ -95,7 +95,8 @@ class BulkPublish2 extends LitElement {
this.validateUrls();
}

setJobErrors(errors) {
setJobErrors(jobErrors, authErrors) {
const errors = [...jobErrors, ...authErrors];
const urls = [];
errors.forEach((error) => {
const matched = this.urls.filter((url) => {
Expand Down Expand Up @@ -323,7 +324,8 @@ class BulkPublish2 extends LitElement {
class="panel-title"
@click=${handleToggle}>
<span class="title">
Job Results
${this.jobs.length ? html`<strong>${this.jobs.length}</strong>` : ''}
Job Result${this.jobs.length > 1 ? 's' : ''}
</span>
<div class="jobs-tools${showList}">
<div
Expand Down Expand Up @@ -380,16 +382,17 @@ class BulkPublish2 extends LitElement {
async submit() {
if (!this.isDisabled()) {
this.processing = 'started';
const { authorized, unauthorized } = await getPublishable(this);
const job = await startJob({
urls: this.urls,
urls: authorized,
process: this.process.toLowerCase(),
useBulk: this.user.permissions[this.process]?.useBulk ?? false,
});
const { complete, error } = processJobResult(job);
this.jobs = [...this.jobs, ...complete];
this.processing = complete.length ? 'job' : false;
if (error.length) {
this.setJobErrors(error);
if (error.length || unauthorized.length) {
this.setJobErrors(error, unauthorized);
} else {
if (this.mode === 'full') this.openJobs = true;
this.reset();
Expand All @@ -407,6 +410,7 @@ class BulkPublish2 extends LitElement {

renderPromptLoader() {
setTimeout(() => {
/* c8 ignore next 4 */
const loader = this.renderRoot.querySelector('.load-indicator');
const message = this.renderRoot.querySelector('.message');
loader?.classList.add('hide');
Expand All @@ -427,6 +431,7 @@ class BulkPublish2 extends LitElement {
const canUse = Object.values(this.user.permissions).filter((perms) => perms.canUse);
if (canUse.length) return html``;
message = 'Current user is not authorized to use Bulk Publishing Tool';
/* c8 ignore next 3 */
} else {
message = 'Please sign in to AEM sidekick to continue';
}
Expand Down
25 changes: 25 additions & 0 deletions libs/blocks/bulk-publish-v2/services.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import userCanPublishPage from '../../tools/utils/publish.js';
import {
PROCESS_TYPES,
getErrorText,
Expand Down Expand Up @@ -246,8 +247,32 @@ const updateRetry = async ({ queue, urls, process }) => {
return newQueue;
};

// publish authentication service
const getPublishable = async ({ urls, process, user }) => {
let publishable = { authorized: [], unauthorized: [] };
if (!isLive(process)) {
publishable.authorized = urls;
} else {
const { permissions, profile } = user;
const live = { permissions: ['read'] };
if (permissions?.publish?.canUse) {
live.permissions.push('write');
}
publishable = await urls.reduce(async (init, url) => {
const result = await init;
const detail = { webPath: new URL(url).pathname, live, profile };
const { canPublish, message } = await userCanPublishPage(detail);
if (canPublish) result.authorized.push(url);
else result.unauthorized.push({ href: url, message });
return result;
}, Promise.resolve(publishable));
}
return publishable;
};

export {
authenticate,
getPublishable,
pollJobStatus,
startJob,
updateRetry,
Expand Down
11 changes: 9 additions & 2 deletions libs/blocks/global-navigation/global-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import {
addMepHighlightAndTargetId,
isDarkMode,
darkIcons,
setDisableAEDState,
getDisableAEDState,
} from './utilities/utilities.js';

import { replaceKey, replaceKeyArray } from '../../features/placeholders.js';
Expand Down Expand Up @@ -837,8 +839,9 @@ class Gnav {

if (!hasActiveLink()) {
const sections = this.elements.mainNav.querySelectorAll('.feds-navItem--section');
const disableAED = getDisableAEDState();

if (sections.length === 1) {
if (!disableAED && sections.length === 1) {
sections[0].classList.add(selectors.activeNavItem.slice(1));
setActiveLink(true);
}
Expand Down Expand Up @@ -1024,7 +1027,11 @@ const getSource = async () => {
export default async function init(block) {
try {
const { mep } = getConfig();
const url = await getSource();
const sourceUrl = await getSource();
const [url, hash = ''] = sourceUrl.split('#');
if (hash === '_noActiveItem') {
setDisableAEDState();
}
const content = await fetchAndProcessPlainHtml({ url });
if (!content) return null;
const gnav = new Gnav({
Expand Down
14 changes: 12 additions & 2 deletions libs/blocks/global-navigation/utilities/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function getAnalyticsValue(str, index) {

export function getExperienceName() {
const experiencePath = getMetadata('gnav-source');
const explicitExperience = experiencePath?.split('/').pop();
const explicitExperience = experiencePath?.split('#')[0]?.split('/').pop();
if (explicitExperience?.length
&& explicitExperience !== 'gnav') return explicitExperience;

Expand Down Expand Up @@ -257,14 +257,24 @@ export function setActiveDropdown(elem) {
});
}

// Disable AED(Active Element Detection)
export const [setDisableAEDState, getDisableAEDState] = (() => {
let disableAED = false;
return [
() => { disableAED = true; },
() => disableAED,
];
})();

export const [hasActiveLink, setActiveLink, getActiveLink] = (() => {
let activeLinkFound;

return [
() => activeLinkFound,
(val) => { activeLinkFound = !!val; },
(area) => {
if (hasActiveLink() || !(area instanceof HTMLElement)) return null;
const disableAED = getDisableAEDState();
if (disableAED || hasActiveLink() || !(area instanceof HTMLElement)) return null;
const { origin, pathname } = window.location;
const url = `${origin}${pathname}`;
const activeLink = [
Expand Down
6 changes: 6 additions & 0 deletions libs/blocks/hero-marquee/hero-marquee.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
decorateTextOverrides,
decorateButtons,
handleObjectFit,
loadCDT,
} from '../../utils/decorate.js';
import { createTag, loadStyle, getConfig } from '../../utils/utils.js';

Expand Down Expand Up @@ -259,5 +260,10 @@ export default async function init(el) {
}
});
decorateTextOverrides(el, ['-heading', '-body', '-detail'], mainCopy);

if (el.classList.contains('countdown-timer')) {
promiseArr.push(loadCDT(copy, el.classList));
}

await Promise.all(promiseArr);
}
6 changes: 4 additions & 2 deletions libs/blocks/library-config/library-config.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ input.sk-library-search-input:focus {
* Fixes block list getting cut off with search
* Margin height equal to search bar height
*/
.sk-library ul.con-blocks-list.inset {
.sk-library ul.con-blocks-list.inset,
.sk-library ul.con-templates-list.inset {
margin-bottom: 39px;
}

Expand Down Expand Up @@ -242,7 +243,8 @@ input.sk-library-search-input:focus {
font-weight: 700;
}

.sk-library .block-group.is-hidden {
.sk-library .block-group.is-hidden,
.con-templates-list .template.is-hidden {
display: none;
}

Expand Down
45 changes: 35 additions & 10 deletions libs/blocks/library-config/library-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { createTag } from '../../utils/utils.js';

const LIBRARY_PATH = '/docs/library/library.json';

async function loadBlocks(content, list, query) {
async function loadBlocks({ content, list, query, type }) {
const { default: blocks } = await import('./lists/blocks.js');
blocks(content, list, query);
blocks(content, list, query, type);
}

async function loadTemplates(content, list) {
async function loadTemplates({ content, list, query, type }) {
const { default: templates } = await import('./lists/templates.js');
templates(content, list);
templates(content, list, query, type);
}

async function loadPlaceholders(content, list) {
Expand All @@ -32,27 +32,47 @@ async function loadPersonalization(content, list) {
personalization(content, list);
}

function addSearch(content, list) {
function addSearch({ content, list, type }) {
const skLibrary = list.closest('.sk-library');
const header = skLibrary.querySelector('.sk-library-header');
let search = skLibrary.querySelector('.sk-library-search');
if (!search) {
search = createTag('div', { class: 'sk-library-search' });
const searchInput = createTag('input', { class: 'sk-library-search-input', placeholder: 'Search...' });
const clear = createTag('div', { class: 'sk-library-search-clear is-hidden' });

searchInput.addEventListener('input', (e) => {
const query = e.target.value;
if (query === '') {
clear.classList.add('is-hidden');
} else {
clear.classList.remove('is-hidden');
}
loadBlocks(content, list, query);

switch (type) {
case 'blocks':
loadBlocks({ content, list, query, type });
break;
case 'templates':
loadTemplates({ content, list, query, type });
break;
default:
}
});
clear.addEventListener('click', (e) => {
e.target.classList.add('is-hidden');
e.target.closest('.sk-library-search').querySelector('.sk-library-search-input').value = '';
loadBlocks(content, list);
const query = e.target.value;

switch (type) {
case 'blocks':
loadBlocks({ content, list, query, type });
break;
case 'templates':
loadTemplates({ content, list, query, type });
break;
default:
}
});
search.append(searchInput);
search.append(clear);
Expand All @@ -67,11 +87,12 @@ async function loadList(type, content, list) {
const query = list.closest('.sk-library').querySelector('.sk-library-search-input')?.value;
switch (type) {
case 'blocks':
addSearch(content, list);
loadBlocks(content, list, query);
addSearch({ content, list, type });
loadBlocks({ content, list, query, type });
break;
case 'templates':
loadTemplates(content, list);
addSearch({ content, list, type });
loadTemplates({ content, list, query, type });
break;
case 'placeholders':
loadPlaceholders(content, list);
Expand Down Expand Up @@ -198,6 +219,10 @@ function createHeader() {
el.classList.remove('inset');
});
skLibrary.classList.remove('allow-back');

// Remove library search if it's been added
const search = skLibrary.querySelector('.sk-library-search');
if (search) search.remove();
});
return header;
}
Expand Down
Loading

0 comments on commit 7c2d611

Please sign in to comment.