Skip to content

Commit

Permalink
Build: (1ae38a2) Merge pull request #105 from 10up/fix/104
Browse files Browse the repository at this point in the history
Ensure commands work in the new iframed Block Editor
  • Loading branch information
dkotter committed Aug 25, 2023
1 parent dfd9943 commit 939280e
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/commands/close-welcome-guide.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const closeWelcomeGuide = () => {
const titleInput = 'h1.editor-post-title__input, #post-title-0';
const closeButtonSelector = '.edit-post-welcome-guide .components-modal__header button';
// Wait for edit page to load
cy.get(titleInput).should('exist');
cy.getBlockEditor().find(titleInput).should('exist');
cy.get('body').then($body => {
if ($body.find(closeButtonSelector).length > 0) {
cy.get(closeButtonSelector).click();
Expand Down
11 changes: 6 additions & 5 deletions lib/commands/create-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,18 @@ const createPost = ({ postType = 'post', title = 'Test Post', content = 'Test co
cy.visit(`/wp-admin/post-new.php?post_type=${postType}`);
const titleInput = 'h1.editor-post-title__input, #post-title-0';
const contentInput = '.block-editor-default-block-appender__content';
// Make sure editor loaded properly.
cy.get(contentInput).should('exist');
// Close Welcome Guide.
cy.closeWelcomeGuide();
// Fill out data.
if (title.length > 0) {
cy.get(titleInput).clear().type(title);
cy.getBlockEditor().find(titleInput).clear().type(title);
}
if (content.length > 0) {
cy.get(contentInput).click();
cy.get('.block-editor-rich-text__editable').first().type(content);
cy.getBlockEditor().find(contentInput).click();
cy.getBlockEditor()
.find('.block-editor-rich-text__editable')
.first()
.type(content);
}
if ('undefined' !== typeof beforeSave) {
beforeSave();
Expand Down
12 changes: 12 additions & 0 deletions lib/commands/get-block-editor.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Get the Block Editor
*
* @returns Block Editor element.
*
* @example
* Find the title input and type in it
* ```
* cy.getBlockEditor().find('.editor-post-title__input').type('Test Post');
* ```
*/
export declare const getBlockEditor: () => Cypress.Chainable<unknown>;
29 changes: 29 additions & 0 deletions lib/commands/get-block-editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBlockEditor = void 0;
const get_iframe_1 = require("../functions/get-iframe");
/**
* Get the Block Editor
*
* @returns Block Editor element.
*
* @example
* Find the title input and type in it
* ```
* cy.getBlockEditor().find('.editor-post-title__input').type('Test Post');
* ```
*/
const getBlockEditor = () => {
// Ensure the editor is loaded.
cy.get('.edit-post-visual-editor').should('exist');
return cy
.get('body')
.then($body => {
if ($body.find('iframe[name="editor-canvas"]').length) {
return (0, get_iframe_1.getIframe)('iframe[name="editor-canvas"]');
}
return $body;
})
.then(cy.wrap); // eslint-disable-line @typescript-eslint/unbound-method
};
exports.getBlockEditor = getBlockEditor;
70 changes: 57 additions & 13 deletions lib/commands/insert-block.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.insertBlock = void 0;
const get_iframe_1 = require("../functions/get-iframe");
/**
* Inserts Block
*
Expand Down Expand Up @@ -35,6 +36,19 @@ const insertBlock = (type, name) => {
search = type;
}
}
// Remove block patterns
/* eslint-disable */
let patterns = [];
let settings = {};
cy.window().then(win => {
settings = win.wp.data.select('core/block-editor').getSettings();
patterns = (settings === null || settings === void 0 ? void 0 : settings.__experimentalBlockPatterns) || [];
if (patterns.length > 0) {
settings.__experimentalBlockPatterns = [];
}
});
cy.wait(500);
/* eslint-enable */
// Open blocks panel
cy.get('.edit-post-header-toolbar__inserter-toggle, .edit-post-header-toolbar .block-editor-inserter__toggle').click();
cy.get('.block-editor-inserter__search')
Expand All @@ -52,26 +66,56 @@ const insertBlock = (type, name) => {
cy.get('.edit-post-header-toolbar__inserter-toggle.is-pressed').click();
}
});
// Add patterns back
if (patterns.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
settings.__experimentalBlockPatterns = patterns;
}
// Remove tailing suffix of sub-blocks
const blockType = type.replace(/^(.*?)\/(.*?)\/[^/]+$/, '$1/$2');
const blockTypeAlt = type.replace('/', '-');
// Get last block of the current type
// Pull from the iframe editor first, if it exists
cy.get('body').then($body => {
if ($body.find(`.wp-block[data-type="${blockType}"]`).length > 0) {
cy.get(`.wp-block[data-type="${blockType}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
if ($body.find('iframe[name="editor-canvas"]').length) {
(0, get_iframe_1.getIframe)('iframe[name="editor-canvas"]').then($iframe => {
if ($iframe.find(`.wp-block[data-type="${blockType}"]`).length > 0) {
(0, get_iframe_1.getIframe)('iframe[name="editor-canvas"]')
.find(`.wp-block[data-type="${blockType}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
});
}
else if ($iframe.find(`.wp-block[data-type="${blockTypeAlt}"]`).length) {
(0, get_iframe_1.getIframe)('iframe[name="editor-canvas"]')
.find(`.wp-block[data-type="${blockTypeAlt}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
});
}
});
}
else if ($body.find(`.wp-block[data-type="${blockTypeAlt}"]`)) {
cy.get(`.wp-block[data-type="${blockTypeAlt}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
});
else {
if ($body.find(`.wp-block[data-type="${blockType}"]`).length > 0) {
cy.get(`.wp-block[data-type="${blockType}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
});
}
else if ($body.find(`.wp-block[data-type="${blockTypeAlt}"]`)) {
cy.get(`.wp-block[data-type="${blockTypeAlt}"]`)
.last()
.then(block => {
const id = block.prop('id');
cy.wrap(id);
});
}
}
});
};
Expand Down
6 changes: 6 additions & 0 deletions lib/functions/get-iframe.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Code taken from the Cypress iframe package.
*
* https://gitlab.com/kgroat/cypress-iframe
*/
export declare const getIframe: Cypress.Chainable['iframe'];
99 changes: 99 additions & 0 deletions lib/functions/get-iframe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"use strict";
/**
* Code taken from the Cypress iframe package.
*
* https://gitlab.com/kgroat/cypress-iframe
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIframe = void 0;
const DEFAULT_OPTS = {
log: true,
timeout: 30000,
};
const DEFAULT_IFRAME_SELECTOR = 'iframe';
function sleep(timeout) {
return new Promise(resolve => setTimeout(resolve, timeout));
}
const frameLoaded = (selector, opts) => {
if (selector === undefined) {
selector = DEFAULT_IFRAME_SELECTOR;
}
else if (typeof selector === 'object') {
opts = selector;
selector = DEFAULT_IFRAME_SELECTOR;
}
const fullOpts = Object.assign(Object.assign({}, DEFAULT_OPTS), opts);
const log = fullOpts.log
? Cypress.log({
name: 'frame loaded',
displayName: 'frame loaded',
message: [selector],
}).snapshot()
: null;
return cy
.get(selector, { log: false })
.then({ timeout: fullOpts.timeout }, ($frame) => __awaiter(void 0, void 0, void 0, function* () {
log === null || log === void 0 ? void 0 : log.set('$el', $frame);
if ($frame.length !== 1) {
throw new Error(`cypress-iframe commands can only be applied to exactly one iframe at a time. Instead found ${$frame.length}`);
}
const contentWindow = $frame.prop('contentWindow');
const hasNavigated = fullOpts.url
? () => {
var _a;
return typeof fullOpts.url === 'string'
? contentWindow.location.toString().includes(fullOpts.url)
: (_a = fullOpts.url) === null || _a === void 0 ? void 0 : _a.test(contentWindow.location.toString());
}
: () => contentWindow.location.toString() !== 'about:blank';
while (!hasNavigated()) {
yield sleep(100);
}
if (contentWindow.document.readyState === 'complete') {
return $frame;
}
const loadLog = Cypress.log({
name: 'Frame Load',
message: [contentWindow.location.toString()],
event: true,
}).snapshot();
yield new Promise(resolve => {
Cypress.$(contentWindow).on('load', resolve);
});
loadLog.end();
log === null || log === void 0 ? void 0 : log.finish();
return $frame;
}));
};
const getIframe = (selector, opts) => {
if (selector === undefined) {
selector = DEFAULT_IFRAME_SELECTOR;
}
else if (typeof selector === 'object') {
opts = selector;
selector = DEFAULT_IFRAME_SELECTOR;
}
const fullOpts = Object.assign(Object.assign({}, DEFAULT_OPTS), opts);
const log = fullOpts.log
? Cypress.log({
name: 'iframe',
displayName: 'iframe',
message: [selector],
}).snapshot()
: null;
return frameLoaded(selector, Object.assign(Object.assign({}, fullOpts), { log: false })).then($frame => {
log === null || log === void 0 ? void 0 : log.set('$el', $frame).end();
const contentWindow = $frame.prop('contentWindow');
return Cypress.$(contentWindow.document.body);
});
};
exports.getIframe = getIframe;
14 changes: 14 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/// <reference types="cypress" />
/// <reference types="cypress" />
/// <reference types="cypress" />
import { checkPostExists } from './commands/check-post-exists';
import { classicCreatePost } from './commands/classic-create-post';
import { insertBlock } from './commands/insert-block';
Expand All @@ -19,6 +22,7 @@ import { login } from './commands/login';
import { createPost } from './commands/create-post';
import { uploadMedia } from './commands/upload-media';
import { checkSitemap } from './commands/check-sitemap-exists';
import { getBlockEditor } from './commands/get-block-editor';
declare global {
namespace Cypress {
interface Chainable<Subject> {
Expand All @@ -43,6 +47,16 @@ declare global {
logout: typeof logout;
login: typeof login;
checkSitemap: typeof checkSitemap;
getBlockEditor: typeof getBlockEditor;
frameLoaded: IframeHandler<JQuery<HTMLElement>>;
iframe: IframeHandler<JQuery<HTMLBodyElement>>;
}
interface IframeHandler<T> {
(options?: Partial<IframeOptions>): Chainable<T>;
(selector: string, options?: Partial<IframeOptions>): Chainable<T>;
}
interface IframeOptions extends Loggable, Timeoutable {
url?: RegExp | string;
}
}
}
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const login_1 = require("./commands/login");
const create_post_1 = require("./commands/create-post");
const upload_media_1 = require("./commands/upload-media");
const check_sitemap_exists_1 = require("./commands/check-sitemap-exists");
const get_block_editor_1 = require("./commands/get-block-editor");
// Register commands
Cypress.Commands.add('checkPostExists', check_post_exists_1.checkPostExists);
Cypress.Commands.add('classicCreatePost', classic_create_post_1.classicCreatePost);
Expand All @@ -46,3 +47,4 @@ Cypress.Commands.add('uploadMedia', upload_media_1.uploadMedia);
Cypress.Commands.add('logout', logout_1.logout);
Cypress.Commands.add('login', login_1.login);
Cypress.Commands.add('checkSitemap', check_sitemap_exists_1.checkSitemap);
Cypress.Commands.add('getBlockEditor', get_block_editor_1.getBlockEditor);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"env": "wp-env",
"env:start": "wp-env start",
"env:stop": "wp-env stop",
"env:destroy": "wp-env destroy",
"postenv:start": "./tests/bin/initialize.sh"
},
"repository": {
Expand Down

0 comments on commit 939280e

Please sign in to comment.