diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index f2bcf7d41b..7165ef7423 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -18,17 +18,31 @@ on:
- "cypress/**"
jobs:
smoke_tests:
- runs-on: ubuntu-latest
+ container:
+ image: cypress/browsers:node-20.14.0-chrome-126.0.6478.114-1-ff-127.0.1-edge-126.0.2592.61-1
+ options: --user root
+ runs-on: self-hosted
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
+
+ - name: 'Create env file'
+ run: |
+ touch ./example/.env
+ echo GATSBY_IMS_SRC="https://auth-stg1.services.adobe.com/imslib/imslib.min.js" >> ./example/.env
+ echo GATSBY_IMS_CONFIG='{"client_id": "stage_adobe_io", "scope": "AdobeID,openid,unified_dev_portal,read_organizations,additional_info.projectedProductContext,additional_info.roles,gnav,read_pc.dma_bullseye,creative_sdk,adobeio_api,service_principals.read,service_principals.write,read_client_secret", "environment": "stg1"}' >> ./example/.env
+ cat ./example/.env
- name: Run Tests
uses: cypress-io/github-action@v5
with:
- build: yarn build
- start: yarn serve
- wait-on: 'http://[::1]:9000'
+ start: yarn dev:https:ci
+ wait-on: 'https://localhost.corp.adobe.com:9000'
+ wait-on-timeout: 150
browser: chrome
config-file: cypress.config.js
- spec: cypress/e2e/smoke.cy.js
+ spec: |
+ cypress/e2e/smoke.cy.js
+ cypress/e2e/get-credentials.cy.js
+ env:
+ NODE_TLS_REJECT_UNAUTHORIZED: '0'
diff --git a/README.md b/README.md
index b4b39ee69f..31763306b3 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,23 @@ Using a theme, all of your default configuration lives in an npm package.
- [Writing Enhanced Markdown](#writing-enhanced-markdown)
- [Metadata with Front matter](#metadata-with-front-matter)
- [OpenAPI](#openapi)
- - [Redocly API Block](#Redocly API Block)
+ - [Redocly API Block](#RedoclyAPIBlock)
+ - [On-premise license keys](#on-premise-license-keys)
+ - [Local development limitation and workaround](#local-development-limitation-and-workaround)
+ - [Full width page](#full-width-page)
+ - [Displaying long API response descriptions](#displaying-long-api-response-descriptions)
+ - [width (optional)](#width-optional)
+ - [typography (optional)](#typography-optional)
+ - [codeblock (optional)](#codeblock-optional)
+ - [disableSidebar (optional)](#disablesidebar-optional)
+ - [disableSearch (optional)](#disablesearch-optional)
+ - [hideTryItPanel (optional)](#hidetryitpanel-optional)
+ - [scrollYOffset (optional)](#scrollyoffset-optional)
+ - [sortOperationsAlphabetically (optional)](#sortoperationsalphabetically-optional)
+ - [sortTagsAlphabetically (optional)](#sorttagsalphabetically-optional)
+ - [jsonSampleExpandLevel (optional)](#jsonsampleexpandlevel-optional)
+ - [generateCodeSamples (optional)](#generatecodesamples-optional)
+ - [requestInterceptor (optional)](#requestinterceptor-optional)
- [JSDoc](#jsdoc)
- [MDX](#mdx)
- [Modular Content System](#modular-content-system)
@@ -121,6 +137,7 @@ Using a theme, all of your default configuration lives in an npm package.
- [Table Block](#table-block)
- [Tabs Block](#tabs-block)
- [Product Card](#product-card)
+ - [Mini Product Card](#product-card)
- [Product Card Grid](#product-card-grid)
- [Resource Card](#resource-card)
- [MiniResourceCard](#miniresourcecard)
@@ -1076,11 +1093,195 @@ We use [Redoc](https://github.com/Redocly/redoc) to render OpenAPI specs. Simply
-### Redocly API Block
+### RedoclyAPIBlock
-We can now host your own open api yaml files and be rendered by Redocly documents. This way can avoid to iframe in and host our own api yaml files in Redocly.
+```js
+
+```
+
+We can now host your own OpenAPI YAML files and have them rendered by Redocly documents. This approach allows us to avoid using iframes and instead host our own API YAML files directly in Redocly.
+
+#### On-premise license keys
+
+When using RedoclyAPIBlock, ensure that GATSBY_REDOCLY_KEY: ${{ secrets.REDOCLY_LICENSE_KEY }} is added to the deploy.yml file in your repository (e.g. add to [build-dev](https://github.com/AdobeDocs/ff-services-docs/blob/24b9b522e7521d7169265871023cccfa1f03f349/.github/workflows/deploy.yml#L145) and [build-production](https://github.com/AdobeDocs/ff-services-docs/blob/24b9b522e7521d7169265871023cccfa1f03f349/.github/workflows/deploy.yml#L252)). Any public repo in the AdobeDocs organization will have access to this development environment [secret](https://github.com/organizations/AdobeDocs/settings/secrets/actions).
+
+Dev-site team is responsible for making sure the license key is up to date, which can be found in redocly account settings -> On-premise license keys.
+
+#### Local development limitation and workaround
+
+Due to the way Redocly API works, it’s not possible to test RedoclyAPIBlock locally:
+![redocly-api-block-on-local](docs/images/redocly-api-block-on-local.png)
+
+To test, temporarily deploy to stage:
+![redocly-api-block-on-stage](docs/images/redocly-api-block-on-stage.png)
+
+#### Full width page
+
+Use [custom layout](#custom-layout) to do a full width page
+
+#### Displaying long API response descriptions
+
+By default, Redocly displays API response descriptions as the button text (styled as one line, no-wrap). If too long, the text could get truncated, and the page widens beyond 100%:
+![redocly-api-block-long-description-without-x-summary](docs/images/redocly-api-block-long-description-without-x-summary.png)
+![redocly-api-block-long-description-without-x-summary-yaml](docs/images/redocly-api-block-long-description-without-x-summary-yaml.png)
+
+For long descriptions, Redocly suggests to use the [x-summary](https://redocly.com/docs/api-reference-docs/specification-extensions/x-summary/) specification extension. If specified, it is used as the response button text, and the description is rendered under the button:
+![redocly-api-block-long-description-with-x-summary](docs/images/redocly-api-block-long-description-with-x-summary.png)
+![redocly-api-block-long-description-with-x-summary-yaml](docs/images/redocly-api-block-long-description-with-x-summary-yaml.png)
+
+#### width (optional)
+
+```js
+
+```
+Sets the width (of the right panel).
+
+Defaults to ```'500px'```
+
+https://redocly.com/docs/api-reference-docs/configuration/theming/#path=rightPanel
+
+#### typography (optional)
+
+```js
+
+```
+
+Controls the appearance of text.
+
+Defaults to ```'fontFamily: `adobe-clean, "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Trebuchet MS", "Lucida Grande", sans-serif`'```
+
+https://redocly.com/docs/api-reference-docs/configuration/theming/#path=typography
+
+#### codeblock (optional)
+
+```js
+
+```
+
+Controls the appearance of code snippets.
+
+Defaults to ```"tokens: { punctuation: { color: 'white' }}"```
+
+https://redocly.com/docs/api-reference-docs/configuration/theming/#path=codeBlock
+
+#### disableSidebar (optional)
+
+```js
+
+```
+
+If set to `true`, hides the navigation sidebar (the left panel). Setting this option to `false` does not disable the search feature.
+
+Defaults to ```false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### disableSearch (optional)
+
+```js
+
+```
+
+Disables search indexing and hides the search box from the API documentation page.
+
+Defaults to ```false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### hideTryItPanel (optional)
+
+```js
+
+```
+
+Disables the Try it console in the right panel.
+
+Defaults to ```false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### scrollYOffset (optional)
+
+```js
+
+```
+
+Specifies a vertical scroll-offset. This is useful when there are fixed positioned elements at the top of the page, such as navbars, headers etc. You can specify the scrollYOffset value as a number - a fixed number of pixels to be used as the offset.
+
+Defaults to ```0```
-When using this block, GATSBY_REDOCLY_KEY : ${{ secrets.REDOCLY_LICENSE_KEY }} will needs to be added in deploy.yml file in the repo.
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+
+#### sortOperationsAlphabetically (optional)
+
+```js
+
+```
+
+When set to `true`, sorts operations in the navigation sidebar and in the middle panel alphabetically.˙
+
+Defaults to ```false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### sortTagsAlphabetically (optional)
+
+```js
+
+```
+
+When set to `true`, sorts tags in the navigation sidebar and in the middle panel alphabetically. Note that only tags will be sorted alphabetically in the middle panel, not the operations associated with each tag. To sort operations alphabetically as well, you must set `sortOperationsAlphabetically` to `true`.
+
+Defaults to ```false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### jsonSampleExpandLevel (optional)
+
+```js
+
+```
+
+Sets the default expand level for JSON payload samples (response and request body). Takes a number >= 1, or the string 'all'.
+
+Defaults to ```2```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality/#theme-object-openapi-schema
+
+#### generateCodeSamples (optional)
+
+```js
+
+```
+
+Controls options for generating code samples, including code sample languages.
+
+Defaults to ```languages: [], skipOptionalParameters: false```
+
+https://redocly.com/docs/api-reference-docs/configuration/functionality#theme-object-openapi-schema
+
+#### requestInterceptor (optional)
+
+```js
+
+
+![Forge the path to customer success](./S_AniConvertToGIF.png)
+
+# Firefly API
+
+Firefly API
+
+- [Learn more](https://developer-stage.adobe.com/)
+
+```
+
+Use `slots` to identify the markdown content:
+
+- `image`(required)
+- `heading`(required)
+- `text`(optional)
+- `buttons`(optional)
+
+Use `repeat` to define how many code sections are part.
+
+
### Edition
The Edition component is used to display the edition of the product.
@@ -2534,6 +2767,8 @@ as a dependency in another site, you can run the command `npm install --save ado
Your site package will show up under `node_modules/[PACKAGE_NAME]` e.g. `node_modules/dev-site-documentation-template`.
+When pointing to a github repo as a dependency and wanting to get the latest change from that dependency, you have to ensure that your package.json is pointing to latest version of that dependecy. Otherwise, if you have already pulled down that dependency and it exists in your `node_modules/`, it won't grab the latest changes. To get around this, simply delete your `node_modules/` and then `yarn install` again.
+
See full example below using a Variant block.
#### Filtering content with Variant Blocks
diff --git a/cypress.config.js b/cypress.config.js
index a34e9572d8..dcccecd614 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -1,15 +1,21 @@
-const { defineConfig } = require('cypress')
-
-module.exports = defineConfig({
- viewportHeight: 900,
- viewportWidth: 1440,
- e2e: {
- // We've imported your old cypress plugins here.
- // You may want to clean this up later by importing these.
- setupNodeEvents(on, config) {
- return require('./cypress/plugins/index.js')(on, config)
- },
- baseUrl: 'http://localhost:9000',
- specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
- },
-})
+const { defineConfig } = require('cypress')
+
+module.exports = defineConfig({
+ viewportHeight: 900,
+ viewportWidth: 1440,
+ e2e: {
+ // We've imported your old cypress plugins here.
+ // You may want to clean this up later by importing these.
+ setupNodeEvents(on, config) {
+ return require('./cypress/plugins/index.js')(on, config)
+ },
+ baseUrl: 'https://localhost.corp.adobe.com:9000',
+ specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
+ },
+ pageLoadTimeout: 500000,
+ userEmail: 'cypress1@adobe.com',
+ userPassword: 'ScotchB33r&1234567',
+ defaultCommandTimeout: 60000,
+ video: false,
+ chromeWebSecurity: false
+})
diff --git a/cypress/e2e/get-credentials.cy.js b/cypress/e2e/get-credentials.cy.js
new file mode 100644
index 0000000000..e6da4b28ee
--- /dev/null
+++ b/cypress/e2e/get-credentials.cy.js
@@ -0,0 +1,199 @@
+const API_KEY = 'apikey';
+const OAUTH_S2S = 'oauths2s';
+
+function init(route) {
+ cy.visit(route).assertRoute(route);
+ cy.expect('button[data-cy="sign-in-btn"]').to.exist;
+ cy.get('button[data-cy="sign-in-btn"]').should('be.visible');
+ cy.get('button[data-cy="sign-in-btn"]').should('be.enabled');
+ cy.get('button[data-cy="sign-in-btn"]').click();
+ cy.login();
+ cy.get('button[data-cy="sign-in-btn"]').should('not.exist');
+ cy.assertRoute(route + '#');
+}
+
+function checkRequestAccessEdgeCase() {
+ cy.get('[data-cy="accessDetails-edgeCase-btn"]').should('be.visible');
+};
+
+function getIframeBody() {
+ return cy.get('iframe[data-cy="request-access-iframe"]')
+ .its('0.contentDocument.body').should('not.be.empty')
+ .then(cy.wrap);
+}
+
+function checkRequestAccess() {
+ cy.get('body').then(($body) => {
+ // if the request is not already sent, send the request
+ if ($body.find('[data-cy="request-access-button"]').length > 0) {
+ cy.get('[data-cy="request-access-button"]').click();
+
+ getIframeBody().find('h3[data-testid="title"]').invoke('text').then((text) => {
+ if (text.trim() !== 'Your request is on its way') {
+ getIframeBody().find('button[data-testid="send-request-button"]').should('exist').click();
+ }
+ });
+ getIframeBody().find('button[data-testid="close-button"]').should('exist').click();
+ }
+ });
+};
+
+function checkReturnFlow(credentialType) {
+ // verify return flow is visible
+ cy.get('[data-cy="return-flow"]').should('be.visible');
+
+ // verify clicking on create new credential button opens the form
+ returnToForm();
+
+ // verify clicking on cancel button closes the form
+ cy.get('[data-cy="cancel-new-credential"]').click();
+ // cy.get('[data-cy="return-flow"]').should('be.visible');
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-cy="return-flow"]').length) {
+ cy.get('[data-cy="return-flow"]').should('be.visible');
+ }
+ });
+
+ // verify clicking on manage projects console button exists
+ cy.get('[data-cy="manage-projects-console"]').should('exist');
+
+ // ensure project picker is visible
+ cy.get('button[data-cy="projects-picker"]').should('be.visible').should('be.enabled');
+
+ // verify all the information is visible based on credential type
+ checkCredential(credentialType);
+};
+
+function checkAPIKey() {
+
+ // Check if the collapse open button is present and click it if it is
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-cy="collapse-open"]').length) {
+ cy.get('[data-cy="collapse-open"]').click();
+ }
+ });
+
+ // verify API key is visible
+ cy.contains('API Key').should('be.visible');
+
+ // verify API key copy button is clickable
+ cy.get('[data-cy="API Key-copyIcon"]').should('be.visible');
+
+ // verify allowed domains copy button is clickable
+ cy.get('[data-cy="Allowed domains-copyIcon"]').should('be.visible');
+
+ // verify IMS Organization ID copy button is clickable
+ cy.get('[data-cy="IMS Organization ID-copyIcon"]').should('exist');
+
+}
+
+function checkOAuthS2S() {
+
+ // Check if the collapse open button is present and click it if it is
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-cy="collapse-open"]').length) {
+ cy.get('[data-cy="collapse-open"]').click();
+ }
+ });
+
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-cy="generate-token"]').length) {
+ cy.get('[data-cy="generate-token"]').should('be.visible');
+ }
+ });
+ // cy.get('button[data-cy="copy-token"]').should('exist');
+ cy.get('[data-cy="credentialName-link"]').should('exist');
+ cy.get('[data-cy="ClientId-copyIcon"]').should('exist');
+ cy.get('[data-cy="retrieve-client-secret"]').should('be.visible');
+ // cy.get('button[data-cy="copy-client-secret"]').should('exist');
+ cy.get('[data-cy="Scopes-copyIcon"]').should('exist');
+ cy.get('[data-cy="IMS Organization ID-copyIcon"]').should('exist');
+ cy.contains('openid, AdobeID, read_organizations, firefly_api, ff_apis').should('exist');
+}
+
+function checkCredential(credentialType) {
+ switch (credentialType) {
+ case API_KEY:
+ checkAPIKey();
+ break;
+ case OAUTH_S2S:
+ checkOAuthS2S();
+ break;
+ }
+
+ cy.get('[data-cy="next-step-button"]').should('exist');
+ if (credentialType !== API_KEY) {
+ cy.get('[data-cy="Manage-Dev-Console-link"]').should('exist');
+ }
+};
+
+function addCredential(credentialType) {
+ const credentialName = `CypressTest${credentialType}${Math.floor(Math.random() * 1000)}`;
+ cy.get('[data-cy="add-credential-name"]').click().should('have.focus');
+ cy.get('[data-cy="add-credential-name"]').type(credentialName).should('have.value', credentialName);
+ if (credentialType === API_KEY) {
+ cy.get('[data-cy="add-allowed-origins"]').click().should('have.focus');
+ cy.get('[data-cy="add-allowed-origins"]').type('localhost:9000').should('have.value', 'localhost:9000');
+ cy.get('[data-cy="download-checkBox"]').check().should('be.checked');
+ cy.get('[data-cy="select-download-language"]').click();
+ cy.get('ul p').contains('JavaScript').click();
+ }
+ cy.get('[data-cy="terms-condition-link"]').should('be.visible');
+ cy.get('[data-cy="update-terms-condition"]').check().should('be.checked');
+ cy.get('[data-cy="create-credential-btn"]').should('be.visible');
+ cy.get('[data-cy="create-credential-btn"]').should('be.enabled');
+ cy.get('[data-cy="create-credential-btn"]').click();
+ if (credentialType === API_KEY) {
+ cy.get('body').then(($body) => {
+ if ($body.find('button[data-cy="restart-download"]').length) {
+ cy.get('button[data-cy="restart-download"]').should('be.visible').should('be.enabled').click();
+ }
+ });
+ }
+ checkCredential(credentialType);
+ cy.get('[data-cy="Restart-new-credential"]').click();
+};
+
+function waitForLoader() {
+ cy.get('div[data-cy="loader"]').should('exist');
+ cy.get('div[data-cy="loader"]').should('not.exist');
+
+}
+
+function selectOrganization(orgName) {
+ cy.get('span[data-cy="change-organization-btn"]').should('be.visible').click();
+ cy.get('button[data-cy="organization-picker"]').should('be.visible').should('be.enabled').click();
+ cy.contains(orgName).should('exist').click();
+ cy.get('button[data-cy="submit-change-organization"]').should('be.visible').should('be.enabled').click();
+ waitForLoader();
+};
+
+function returnToForm() {
+ cy.get('[data-cy="create-new-credential"]').should('be.visible');
+ cy.get('[data-cy="create-new-credential"]').click();
+ cy.get('[data-cy="credential-form"]').should('be.visible');
+}
+
+describe('Get Credentials Test', () => {
+ it('API Key credential', () => {
+ init('/getCredential/');
+ checkReturnFlow(API_KEY);
+ selectOrganization('AdobeIOTestingOrg');
+ checkReturnFlow(API_KEY);
+ // return to the form
+ returnToForm();
+ addCredential(API_KEY);
+ });
+
+ it('OAuth S2S credential', () => {
+ init('/get-credential-oauth/');
+ checkRequestAccessEdgeCase();
+ selectOrganization('Romans entp org');
+ checkRequestAccess();
+ selectOrganization('MAC New Feature Testing');
+ checkReturnFlow(OAUTH_S2S);
+ // return to the form
+ returnToForm();
+ addCredential(OAUTH_S2S);
+ });
+});
\ No newline at end of file
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 81279abd7c..e7b7c86fcf 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -1,29 +1,134 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add("login", (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
-
-Cypress.Commands.add(`assertRoute`, (route) => {
- cy.url().should(`equal`, `${window.location.origin}${route}`);
-});
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
+const baseUrl = Cypress.config('baseUrl');
+
+Cypress.Commands.add(`assertRoute`, (route) => {
+ cy.url().should(`equal`, `${window.location.origin}${route}`);
+});
+
+Cypress.Commands.add('login', () => {
+ // wait for page to settle
+ cy.wait(5000);
+
+ cy.get('body').then(($body) => {
+ if ($body.find("[data-id='EmailPage-EmailField']").length) {
+ cy.setCredentials();
+ }
+ });
+});
+
+/**
+ * @description set credentials on the login page code taken from
+ * https://git.corp.adobe.com/pixel/cypress-acrites/blob/c398947b29f8315c611ae0438afe5f4e3e2b1d88/plugins/e2e-core-commands/src/commands/login.js#L52
+ * @method setCredentials
+ * @param {String} login login email used to login
+ * @param {String} password password used to login
+ */
+Cypress.Commands.add('setCredentials', () => {
+ const login = Cypress.config().userEmail;
+ const password = Cypress.config().userPassword;
+ // set login value
+ cy.get("[data-id='EmailPage-EmailField']").should('be.visible').should('be.enabled').type(login);
+
+ // click to continue
+ cy.get("[data-id='EmailPage-ContinueButton']").should('be.visible').should('be.enabled').click();
+
+ // wait to pass the login step
+ cy.get('.EmailPage').should('not.exist');
+
+ // case `Select an account` page
+ cy.get('body').then(($body) => {
+ if ($body.find('.IdentitiesPage').length) {
+ // we have the UI to select type of account
+ cy.get('.IdentitiesPage').should('be.visible');
+
+ // click to select personal account
+ cy.get("[data-id='AccountChooser-AccountList-individual']").click();
+ }
+ });
+
+ // set password value
+ cy.get("[data-id='PasswordPage-PasswordField']").should('be.visible').should('be.enabled').type(password);
+
+ // click to continue
+ cy.get("[data-id='PasswordPage-ContinueButton']").should('be.visible').should('be.enabled').click();
+
+ // wait to pass the password step
+ cy.get('.PasswordPage').should('not.exist');
+
+ // case `Introducing profile selection` page
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-id="PP-T2E-ProfilesSetup-Introduction"]').length) {
+ cy.get('[data-id="PP-T2E-ProfilesSetup-Introduction-ContinueButton"]').should('be.visible').click();
+ }
+ });
+
+ // case `Entreprise configuration` page
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-id="PP-T2E-ProfilesSetup-Complete"]').length) {
+ cy.get('[data-id="PP-T2E-ProfilesSetup-Complete-ContinueButton"]').should('be.visible').click();
+ }
+ });
+
+ // case `Want to signin without your password` page
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-id="PasswordlessOptInPP-Page"]').length) {
+ cy.get('[data-id="PasswordlessOptInPP-continue-button"]').should('be.visible').click();
+ }
+ });
+
+ // case `Get updates about Adobe products and services` page
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-id="MarketingConsent"]').length) {
+ cy.get('[data-id="PP-RecordMarketingConsent-ContinueBtn"]').should('be.visible').click();
+ }
+ });
+
+ // case `Add a backup email address` page
+ cy.get('body').then(($body) => {
+ if ($body.find('[data-id="PP-AddSecondaryEmail-Page"]').length) {
+ cy.contains('Not now').should('be.visible').click();
+ }
+ });
+
+ // case `Add a mobile phone number` page
+ cy.get('body').then(($body) => {
+ if ($body.text().includes('Add a mobile phone number')) {
+ cy.contains('Not now').should('be.visible').click();
+ }
+ });
+
+ cy.get('body').then(($body) => {
+ if ($body.text().includes('Select a profile to sign in')) {
+ cy.contains('Personal Profile').should('be.visible').click();
+ }
+ });
+
+ cy.intercept('POST', 'https://adobeid-na1-stg1.services.adobe.com/ims/check/v6/token*', (req) => {
+ console.log('intercepted ims token exchange request');
+ req.headers['Origin'] = new URL(baseUrl).origin;
+ }).as('imsTokenExchange');
+});
diff --git a/docs/images/mini-product-card.png b/docs/images/mini-product-card.png
new file mode 100644
index 0000000000..e71a576c25
Binary files /dev/null and b/docs/images/mini-product-card.png differ
diff --git a/docs/images/redocly-api-block-long-description-with-x-summary-yaml.png b/docs/images/redocly-api-block-long-description-with-x-summary-yaml.png
new file mode 100644
index 0000000000..258c67f479
Binary files /dev/null and b/docs/images/redocly-api-block-long-description-with-x-summary-yaml.png differ
diff --git a/docs/images/redocly-api-block-long-description-with-x-summary.png b/docs/images/redocly-api-block-long-description-with-x-summary.png
new file mode 100644
index 0000000000..157258f508
Binary files /dev/null and b/docs/images/redocly-api-block-long-description-with-x-summary.png differ
diff --git a/docs/images/redocly-api-block-long-description-without-x-summary-yaml.png b/docs/images/redocly-api-block-long-description-without-x-summary-yaml.png
new file mode 100644
index 0000000000..6fad9937cd
Binary files /dev/null and b/docs/images/redocly-api-block-long-description-without-x-summary-yaml.png differ
diff --git a/docs/images/redocly-api-block-long-description-without-x-summary.png b/docs/images/redocly-api-block-long-description-without-x-summary.png
new file mode 100644
index 0000000000..0ba55d172b
Binary files /dev/null and b/docs/images/redocly-api-block-long-description-without-x-summary.png differ
diff --git a/docs/images/redocly-api-block-on-local.png b/docs/images/redocly-api-block-on-local.png
new file mode 100644
index 0000000000..87b35e8d42
Binary files /dev/null and b/docs/images/redocly-api-block-on-local.png differ
diff --git a/docs/images/redocly-api-block-on-stage.png b/docs/images/redocly-api-block-on-stage.png
new file mode 100644
index 0000000000..1178118d19
Binary files /dev/null and b/docs/images/redocly-api-block-on-stage.png differ
diff --git a/example/certs/cert.crt b/example/certs/cert.crt
new file mode 100644
index 0000000000..b85430f7e0
--- /dev/null
+++ b/example/certs/cert.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDYTCCAkmgAwIBAgITdQO1/vrfGcXYta2eGROZ5f7NmjANBgkqhkiG9w0BAQsF
+ADAyMRMwEQYDVQQKDApBZG9iZSBJbmMuMRswGQYDVQQDDBJSb290TG9jYWxBZG9i
+ZUNlcnQwHhcNMjQwNzE5MjA1MDU3WhcNMjUxMjAxMjA1MDU3WjAjMSEwHwYDVQQD
+DBhsb2NhbGhvc3QuY29ycC5hZG9iZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDsT2KUTea2IAOf+8ilTMqPVE9SKqI+IeiV2XjtZcqRw9FMeH7a
+Ck4DQjIqjToMH9EmXM7LQdqqLzShlrcBs0G9dc6+1JzVCv+XUzmVgL+lrv13mvQP
+8yuxNLUZqQC2GAR6ur93iFiGqBnHwJ7IK35fw9YdGtoKmfAp1Ff/VmWPnd2GOsqd
+FyHWr8lic/g5dDqkDymzgnBmt8ok3D2Jz8cDqbITYTRgCGDK+iZUE2JrQvEduznj
+vvJSzVncWkjyQtq19GsiE0KADdVEo7nqR2WcLVKuoyUbVStDNgPjfMd1quBrOd6G
+QWEbTcalwDba1DaLsDmVgm+0CyFz8FVfsPfPAgMBAAGjfzB9MB8GA1UdIwQYMBaA
+FLClBzlsV0KaFwHEyVN3mYMY2Od5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMCMG
+A1UdEQQcMBqCGGxvY2FsaG9zdC5jb3JwLmFkb2JlLmNvbTAdBgNVHQ4EFgQU4Vdm
+BiEsgbxOJxeyKNYtzAFhLyUwDQYJKoZIhvcNAQELBQADggEBAEnIxw9fWMhs6lc6
+mL5QfRhFsd7yB54mfHK626YWfw8mieTn4uOZkfGGXPXYTkEQBLoK/2KNjHZbQh7f
+5o+ipZIpgUztMGFKKgocsxd/acWCZD/iDfvh7cv49DnNK5tEKz+cUz9nT1dkzf5D
+/wfrtKCs9fzBFJJT/hSD/2Ez2kY28pSvPYzArez1r/uJeiSmpfet2WSqNckk2mKz
+6KAosvsEvo0tt2mIv1Q/zBgHrmFdmoBTnbZzFv3j/7I1UTPIMTePQkz0UuY9KUlU
+J0Xqc3EF+YdextrSZ5S+PZLsxmOEUU6wG2Ex5KXNdR5OYFmRA44MJkoi0CDoakTx
+IZ0695Y=
+-----END CERTIFICATE-----
diff --git a/example/certs/key.key b/example/certs/key.key
new file mode 100644
index 0000000000..4ea9334b03
--- /dev/null
+++ b/example/certs/key.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsT2KUTea2IAOf
++8ilTMqPVE9SKqI+IeiV2XjtZcqRw9FMeH7aCk4DQjIqjToMH9EmXM7LQdqqLzSh
+lrcBs0G9dc6+1JzVCv+XUzmVgL+lrv13mvQP8yuxNLUZqQC2GAR6ur93iFiGqBnH
+wJ7IK35fw9YdGtoKmfAp1Ff/VmWPnd2GOsqdFyHWr8lic/g5dDqkDymzgnBmt8ok
+3D2Jz8cDqbITYTRgCGDK+iZUE2JrQvEduznjvvJSzVncWkjyQtq19GsiE0KADdVE
+o7nqR2WcLVKuoyUbVStDNgPjfMd1quBrOd6GQWEbTcalwDba1DaLsDmVgm+0CyFz
+8FVfsPfPAgMBAAECggEAR1NKuOKugUg2b+JqVGJSPWLAMlfF8qT/c8NZOaZgtxB4
+qvEvsJYtp9QiGi/YVnKACWk3zafJ3VY0N5WrFStK62mUhorb733LWZx4JAThU5v2
+y1QM2IeYJ3t2MhGNsmibaYPWaLjRp4szhNRB2L8v/K26gbxqFYsTLzz1do9YRjlW
+eoDjTb/G3lX+hMksD94CNL1msXuKYLwvIw+gmjJUGI+AdCuVb9Hj9E30E1J1Cv6a
+MKAplhqQsJ7MLPU8fZqhaRAtrHwmQlLofskm4yf0b3AtccOtcJ23vkglsxw5SpYs
+xAZx0kEMRM6j81pQURV+HJDhbJ6ESACE3htDjz0bOQKBgQD2ipZaDfJ3A15/b5gF
+NnbTKJikhVwcj3Iz9IFYC0vru4b86Hn9gPRagSwPktoMQTb43sE1JBh8FLgfpliF
+C1uUVUM74ZW9z6z/v6kRC3E49zLb92iNrl9CVI5PvIVsSeMq3kiiMGXjuhT55UM3
+e4ecHTv0te9pP6ZXjoYJMPzS2wKBgQD1YE+pOQCNSn/hgwv6WV/3pKypqho3QxT6
+sOh7r170ugPQzWlpvXOQLgHnD54zFhuxBloiRzZ0O/D0VDHP4AehBoG0cH5PooCo
++mDC09nk2ggN1jxSs4rqhipF3A+DW4QcLP1ggui/jXiD1qDMcQTWw9SsBncFSH99
+NVq++ArPHQKBgQDryzBxgNVdLkO67igfFDAhVLpo34NxbWB0gG0Un/lExF4elNnX
+svYBeXmCi5kwD09cRu/Su2sPgWF4I8iVtn8oJ0PeiaqFl5KGJ/Cy9JadPQ/PgZjl
+qNhCwEw7xrp1D1XNMjuVo2RPoTFer/7Rmbvhe7RUH42Sw+V76DwZnliv8QKBgQDN
+zwdh/46n87nJM7qDNB2bQAMWl7c/bMOW9XU58MErcS4sH25wI1hfsUclP+NIJB37
+4EEPiT1yRqh2tnvFSLn9ZNC7wLMhJkLV+JPaNgkHu5yPxoZ4M2GsDfY8/DQC0GrB
+mza2kXaY3BceNZJPh+gwHrctxopj4wgTxAGmNbQTPQKBgE9sJgJRKUxcvGbxL/g7
+y4iSAH9fRxK2ixBd/tlRtLH7BvyYEx+iYGGYJd7QgCM3JYkenwvaKdVrMbFc3jFb
+TUU3AEVNDwa1Thaoclw/wU39Ciko7x4feoLQV3uphmuFSKqt8N/oAqAkrYiMNRC9
+Yx8TXEtC49SFPj3vabhJzIYt
+-----END PRIVATE KEY-----
diff --git a/example/gatsby-config.js b/example/gatsby-config.js
index cbede411a5..c26163269d 100644
--- a/example/gatsby-config.js
+++ b/example/gatsby-config.js
@@ -10,6 +10,8 @@
* governing permissions and limitations under the License.
*/
+const { createProxyMiddleware } = require("http-proxy-middleware");
+
module.exports = {
pathPrefix: process.env.PATH_PREFIX || '/example/',
siteMetadata: {
@@ -35,6 +37,14 @@ module.exports = {
title: 'Adobe Analytics',
path: 'index.md'
},
+ {
+ title: 'Get API Key credential',
+ path: "/getCredential"
+ },
+ {
+ title: 'Get OAuth S2S credential',
+ path: "/get-credential-oauth"
+ },
{
title: 'Docs',
menu: [
@@ -105,7 +115,7 @@ module.exports = {
},
{
title: 'Community Forums',
- path: 'https://adobe.com/communities/index.html'
+ path: 'https://community.adobe.com/'
}
]
},
@@ -249,9 +259,31 @@ module.exports = {
}
]
}
+
]
},
plugins: [
`@adobe/gatsby-theme-aio`
],
+ developMiddleware: app => {
+ app.use(
+ "/console/api",
+ createProxyMiddleware({
+ target: "https://developer-stage.adobe.com/console/api",
+ secure: false,
+ changeOrigin: true,
+ })
+ );
+ app.use("/templates", createProxyMiddleware({
+ target: "https://developer-stage.adobe.com/templates",
+ secure: false,
+ changeOrigin: true,
+ }));
+
+ app.use("/ims", createProxyMiddleware({
+ target: "https://ims-na1-stg1.adobelogin.com/ims",
+ secure: false,
+ changeOrigin: true,
+ }));
+ },
};
diff --git a/example/package.json b/example/package.json
index 0acdb9a6ec..f967f09d34 100644
--- a/example/package.json
+++ b/example/package.json
@@ -4,7 +4,8 @@
"version": "0.0.1",
"dependencies": {
"@adobe/gatsby-theme-aio": "*",
- "gatsby": "4.22.0"
+ "gatsby": "4.22.0",
+ "http-proxy-middleware": "^3.0.0"
},
"scripts": {
"start": "gatsby build && gatsby serve",
diff --git a/example/src/pages/credential/GetCredentialApiKey.js b/example/src/pages/credential/GetCredentialApiKey.js
new file mode 100644
index 0000000000..199ba3d0a7
--- /dev/null
+++ b/example/src/pages/credential/GetCredentialApiKey.js
@@ -0,0 +1,136 @@
+import React from 'react'
+import { GetCredential } from '../../../../packages/gatsby-theme-aio/src/components/GetCredential';
+import creativeCloud from "../../pages/creative_cloud/images/cc-icon.png";
+
+const GetCredentialApiKey = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
API key credential
+
Submitting this form creates an API Key credential. The API key credential identifies your application to Adobe servers and can help accept or reject requests originating from certain domains.
Submitting this form creates an API Key credential. The API key credential identifies your application to Adobe servers and can help accept or reject requests originating from certain domains.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.
Submitting this form creates an API Key credential. The API key credential identifies your application to Adobe servers and can help accept or reject requests originating from certain domains.
Submitting this form created an API Key credential. The API key credential identifies your application to Adobe servers and can help accept or reject requests originating from certian domains.
An API Key credential was created. The API key credential identifies your application to Adobe servers and can help accept or reject request originating from certain domains.
+ This credential allows you to use industry standard OAuth2.0
+ libraries to generate access tokens using the OAuth 2.0 client
+ credentials grant type.
+
+ This credential allows you to use industry standard OAuth2.0
+ libraries to generate access tokens using the OAuth 2.0 client
+ credentials grant type.
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.
+ This credential allows you to use industry standard OAuth2.0
+ libraries to generate access tokens using the OAuth 2.0 client
+ credentials grant type.
+
- An organization is the entity that functions like a log-in company that spans all Adobe products and applications. Most often, an organization is your company name.However, a company can have many organizations. Change the organization here.
-
-
-
-
- Organization
-
-
-
-
div > .spectrum-Picker {
- width: 100% !important;
- height: 20px;
- }
-
- & > div > div {
- width: 86%;
- left: 9%;
- height : 40%;
-
- @media screen and (min-width:${MIN_MOBILE_WIDTH}) and (max-width:${MAX_MOBILE_WIDTH}){
- width: 82%;
- left: 15%;
- }
-
- @media screen and (min-width:${MIN_TABLET_SCREEB_WIDTH}) and (max-width:${MAX_TABLET_SCREEN_WIDTH}){
- width: 91%;
- left: 7%;
- }
-
- }
-
- & > div > .spectrum-Picker-popover > ul > li > div > div {
- margin : 0 ;
- }
-
- & > div > .spectrum-Picker-popover > ul > li > div > div > svg {
- @media screen and (min-width:${MIN_MOBILE_WIDTH}) and (max-width:${MAX_TABLET_SCREEN_WIDTH}){
- margin: 3px;
- padding: 0;
- }
- }
-
- padding: 5px;
- border-radius: 3px;
- border: 1px solid #D0D0D0 !important;
-
- ` }
- >
- {
- return {
- title: organs?.name,
- selected: k === selectedIndex
- }
- })}
- onChange={(index) => {
- setSelectedIndex(index);
- }}
- />
-
- {credentialForm?.paragraph}
+ className="spectrum-Body spectrum-Body--sizeS"
+ css={css`
+ color: var(--spectrum-global-color-gray-800);
+ display: inline-flex;
+ `}
+ onClick={() => setIsShow(true)}>
+ {selectedOrganization.type === "developer" ?
+ "You're creating this credential in your personal developer organization" :
+ <>You're creating this credential in [{selectedOrganization?.name}].>}
+
- }
-
- You're creating this credential in {organization?.type === "developer" ? "in your personal developer organization" : [{organization?.name}] }.
- {showOrganization &&
- }
-