diff --git a/packages/react-native-editor/__device-tests__/.eslintrc.js b/packages/react-native-editor/__device-tests__/.eslintrc.js
new file mode 100644
index 00000000000000..8be64e4c826a0b
--- /dev/null
+++ b/packages/react-native-editor/__device-tests__/.eslintrc.js
@@ -0,0 +1,6 @@
+module.exports = {
+ extends: '../.eslintrc.js',
+ globals: {
+ editorPage: true, // Defined in 'jest_ui_test_environment.js'
+ },
+};
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js
index 2d8ce89ffda3ef..8721f11c793554 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js
@@ -1,50 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
- swipeDown,
- clickMiddleOfElement,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid, swipeDown, clickMiddleOfElement } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests for Block insertion', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const paragraphBlockName = 'Paragraph';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- // wait for the block editor to load
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to insert block into post', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
let paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -54,29 +19,33 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
// Should have 3 paragraph blocks at this point
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
await paragraphBlockElement.click();
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
3
);
await paragraphBlockElement.click();
await editorPage.sendTextToParagraphBlock( 3, testData.mediumText );
- await editorPage.verifyHtmlContent( testData.blockInsertionHtml );
+ const html = await editorPage.getHtmlContent();
+
+ expect( testData.blockInsertionHtml.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
// wait for the block editor to load and for accessibility ids to update
- await driver.sleep( 3000 );
+ await editorPage.driver.sleep( 3000 );
// Workaround for now since deleting the first element causes a crash on CI for Android
if ( isAndroid() ) {
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
3,
{
autoscroll: true,
@@ -84,37 +53,43 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
);
await paragraphBlockElement.click();
- await editorPage.removeBlockAtPosition( paragraphBlockName, 3 );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph, 3 );
for ( let i = 3; i > 0; i-- ) {
// wait for accessibility ids to update
- await driver.sleep( 1000 );
+ await editorPage.driver.sleep( 1000 );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
i,
{
autoscroll: true,
}
);
await paragraphBlockElement.click();
- await editorPage.removeBlockAtPosition( paragraphBlockName, i );
+ await editorPage.removeBlockAtPosition(
+ blockNames.paragraph,
+ i
+ );
}
} else {
for ( let i = 4; i > 0; i-- ) {
// wait for accessibility ids to update
- await driver.sleep( 1000 );
+ await editorPage.driver.sleep( 1000 );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
+ );
+ await clickMiddleOfElement(
+ editorPage.driver,
+ paragraphBlockElement
);
- await clickMiddleOfElement( driver, paragraphBlockElement );
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
}
}
} );
it( 'should be able to insert block at the beginning of post from the title', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
let paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -127,29 +102,24 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
await editorPage.dismissKeyboard();
}
- await swipeDown( driver );
+ await swipeDown( editorPage.driver );
const titleElement = await editorPage.getTitleElement( {
autoscroll: true,
} );
await titleElement.click();
await titleElement.click();
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
- await clickMiddleOfElement( driver, paragraphBlockElement );
+ await clickMiddleOfElement( editorPage.driver, paragraphBlockElement );
await editorPage.sendTextToParagraphBlock( 1, testData.mediumText );
await paragraphBlockElement.click();
- await editorPage.verifyHtmlContent(
- testData.blockInsertionHtmlFromTitle
- );
- } );
+ const html = await editorPage.getHtmlContent();
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ expect( testData.blockInsertionHtmlFromTitle.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-columns.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-columns.test.js
index e7b0b25688a272..b57ea2588d7ee6 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-columns.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-columns.test.js
@@ -1,38 +1,10 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
+import { blockNames } from './pages/editor-page';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor Columns Block test', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const columnsBlockName = 'Columns';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to handle a columns width unit from web', async () => {
await editorPage.setHtmlContent(
testData.columnsWithDifferentUnitsHtml
@@ -42,13 +14,6 @@ describe( 'Gutenberg Editor Columns Block test', () => {
await columnsBlock.click();
expect( columnsBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( columnsBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.columns );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-cover.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-cover.test.js
index 574deffc37cd36..9ae321e3b39820 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-cover.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-cover.test.js
@@ -1,48 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor Cover Block test', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const coverBlockName = 'Cover';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should displayed properly and have properly converted height (ios only)', async () => {
await editorPage.setHtmlContent( testData.coverHeightWithRemUnit );
const coverBlock = await editorPage.getBlockAtPosition(
- coverBlockName
+ blockNames.cover
);
// Temporarily this test is skipped on Android,due to the inconsistency of the results,
@@ -57,13 +25,6 @@ describe( 'Gutenberg Editor Cover Block test', () => {
await coverBlock.click();
expect( coverBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( coverBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.cover );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-file.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-file.test.js
index ef2375ff339175..040e93d8ac2587 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-file.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-file.test.js
@@ -1,40 +1,12 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
+import { blockNames } from './pages/editor-page';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor File Block tests @canary', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const fileBlockName = 'File';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a file block', async () => {
- await editorPage.addNewBlock( fileBlockName );
+ await editorPage.addNewBlock( blockNames.file );
const block = await editorPage.getFirstBlockVisible();
await expect( block ).toBeTruthy();
} );
@@ -43,16 +15,12 @@ describe( 'Gutenberg Editor File Block tests @canary', () => {
const block = await editorPage.getFirstBlockVisible();
block.click();
- await driver.sleep( 1000 );
+ await editorPage.driver.sleep( 1000 );
await editorPage.chooseMediaLibrary();
- await editorPage.verifyHtmlContent( testData.fileBlockPlaceholder );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ const html = await editorPage.getHtmlContent();
+ expect( testData.fileBlockPlaceholder.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js
index 5872ad69803d0f..37211a5db2e0bb 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Gallery Block tests', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const galleryBlockName = 'Gallery';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a gallery block', async () => {
- await editorPage.addNewBlock( galleryBlockName );
+ await editorPage.addNewBlock( blockNames.gallery );
const galleryBlock = await editorPage.getBlockAtPosition(
- galleryBlockName
+ blockNames.gallery
);
expect( galleryBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( galleryBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.gallery );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js
index 3a40a08df918fa..507ec388652945 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js
@@ -1,48 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests @canary', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const paragraphBlockName = 'Paragraph';
- const headingBlockName = 'Heading';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to create a post with heading and paragraph blocks', async () => {
- await editorPage.addNewBlock( headingBlockName );
+ await editorPage.addNewBlock( blockNames.heading );
let headingBlockElement = await editorPage.getBlockAtPosition(
- headingBlockName
+ blockNames.heading
);
if ( isAndroid() ) {
await headingBlockElement.click();
@@ -53,9 +20,9 @@ describe( 'Gutenberg Editor tests @canary', () => {
false
);
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
let paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
await editorPage.typeTextToParagraphBlock(
@@ -63,9 +30,9 @@ describe( 'Gutenberg Editor tests @canary', () => {
testData.mediumText
);
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
3
);
await editorPage.typeTextToParagraphBlock(
@@ -73,9 +40,9 @@ describe( 'Gutenberg Editor tests @canary', () => {
testData.mediumText
);
- await editorPage.addNewBlock( headingBlockName );
+ await editorPage.addNewBlock( blockNames.heading );
headingBlockElement = await editorPage.getBlockAtPosition(
- headingBlockName,
+ blockNames.heading,
4
);
await editorPage.typeTextToParagraphBlock(
@@ -83,9 +50,9 @@ describe( 'Gutenberg Editor tests @canary', () => {
testData.heading
);
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
5
);
await editorPage.typeTextToParagraphBlock(
@@ -93,11 +60,4 @@ describe( 'Gutenberg Editor tests @canary', () => {
testData.mediumText
);
} );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
- } );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js
index a96e61a1c133e4..d0f28f6c68249f 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js
@@ -1,49 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
- clickMiddleOfElement,
- swipeUp,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid, clickMiddleOfElement, swipeUp } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor Image Block tests @canary', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const imageBlockName = 'Image';
- const paragraphBlockName = 'Paragraph';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add an image block', async () => {
- await editorPage.addNewBlock( imageBlockName );
- let imageBlock = await editorPage.getBlockAtPosition( imageBlockName );
+ await editorPage.addNewBlock( blockNames.image );
+ let imageBlock = await editorPage.getBlockAtPosition(
+ blockNames.image
+ );
// Can only add image from media library on iOS
if ( ! isAndroid() ) {
@@ -52,21 +19,21 @@ describe( 'Gutenberg Editor Image Block tests @canary', () => {
// Workaround because of #952
const titleElement = await editorPage.getTitleElement();
- await clickMiddleOfElement( driver, titleElement );
+ await clickMiddleOfElement( editorPage.driver, titleElement );
await editorPage.dismissKeyboard();
// end workaround
imageBlock = await editorPage.getBlockAtPosition( imageBlock );
- await swipeUp( driver, imageBlock );
+ await swipeUp( editorPage.driver, imageBlock );
await editorPage.enterCaptionToSelectedImageBlock(
testData.imageCaption,
true
);
await editorPage.dismissKeyboard();
}
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
if ( isAndroid() ) {
@@ -77,14 +44,11 @@ describe( 'Gutenberg Editor Image Block tests @canary', () => {
// skip HTML check for Android since we couldn't add image from media library
if ( ! isAndroid() ) {
- await editorPage.verifyHtmlContent( testData.imageShorteHtml );
- }
- } );
+ const html = await editorPage.getHtmlContent();
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
+ expect( testData.imageShorteHtml.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
}
- await stopDriver( driver );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js
index 160965d1afe967..a5b8ec8d1a9eda 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Latest Post Block tests', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const lastPostBlockName = 'Latest Posts';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a Latests-Posts block', async () => {
- await editorPage.addNewBlock( lastPostBlockName );
+ await editorPage.addNewBlock( blockNames.latestPosts );
const latestPostsBlock = await editorPage.getBlockAtPosition(
- lastPostBlockName
+ blockNames.latestPosts
);
expect( latestPostsBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( lastPostBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.latestPosts );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js
index 09fc2ce7d1d5b3..89d04d0d2cb1cc 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js
@@ -1,47 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- isAndroid,
- isLocalEnvironment,
- setupDriver,
- stopDriver,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests for List block @canary', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const listBlockName = 'List';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a new List block', async () => {
- await editorPage.addNewBlock( listBlockName );
+ await editorPage.addNewBlock( blockNames.list );
const listBlockElement = await editorPage.getBlockAtPosition(
- listBlockName
+ blockNames.list
);
// Click List block on Android to force EditText focus
if ( isAndroid() ) {
@@ -64,13 +32,14 @@ describe( 'Gutenberg Editor tests for List block @canary', () => {
);
// switch to html and verify html
- await editorPage.verifyHtmlContent( testData.listHtml );
+ const html = await editorPage.getHtmlContent();
+ expect( testData.listHtml.toLowerCase() ).toBe( html.toLowerCase() );
} );
// This test depends on being run immediately after 'should be able to add a new List block'
it( 'should update format to ordered list, using toolbar button', async () => {
let listBlockElement = await editorPage.getBlockAtPosition(
- listBlockName
+ blockNames.list
);
// Click List block to force EditText focus
@@ -80,18 +49,15 @@ describe( 'Gutenberg Editor tests for List block @canary', () => {
await editorPage.clickOrderedListToolBarButton();
// switch to html and verify html
- await editorPage.verifyHtmlContent( testData.listHtmlOrdered );
-
+ const html = await editorPage.getHtmlContent();
+ expect( testData.listHtmlOrdered.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
// Remove list block to return editor to empty state
- listBlockElement = await editorPage.getBlockAtPosition( listBlockName );
+ listBlockElement = await editorPage.getBlockAtPosition(
+ blockNames.list
+ );
await listBlockElement.click();
- await editorPage.removeBlockAtPosition( listBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.list );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js
index a39edd83c9fc29..a08fab00043b4c 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js
@@ -1,47 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests for List block (end)', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const listBlockName = 'List';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to end a List block', async () => {
- await editorPage.addNewBlock( listBlockName );
+ await editorPage.addNewBlock( blockNames.list );
const listBlockElement = await editorPage.getBlockAtPosition(
- listBlockName
+ blockNames.list
);
// Click List block on Android to force EditText focus
@@ -61,13 +29,9 @@ describe( 'Gutenberg Editor tests for List block (end)', () => {
// send an Enter
await editorPage.sendTextToListBlock( listBlockElement, '\n' );
- await editorPage.verifyHtmlContent( testData.listEndedHtml );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ const html = await editorPage.getHtmlContent();
+ expect( testData.listEndedHtml.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js
index 3ce5a3b9fece8a..dbde8dbcfaf6f2 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js
@@ -1,48 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- backspace,
- isAndroid,
- isLocalEnvironment,
- setupDriver,
- stopDriver,
-} from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
+import { backspace, isAndroid } from './helpers/utils';
describe( 'Gutenberg Editor tests for List block', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const listBlockName = 'List';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
// Prevent regression of https://github.com/wordpress-mobile/gutenberg-mobile/issues/871
it( 'should handle spaces in a list', async () => {
- await editorPage.addNewBlock( listBlockName );
+ await editorPage.addNewBlock( blockNames.list );
let listBlockElement = await editorPage.getBlockAtPosition(
- listBlockName
+ blockNames.list
);
// Click List block on Android to force EditText focus
if ( isAndroid() ) {
@@ -59,20 +26,18 @@ describe( 'Gutenberg Editor tests for List block', () => {
await editorPage.sendTextToListBlock( listBlockElement, backspace );
// switch to html and verify html
- await editorPage.verifyHtmlContent( `
+ const html = await editorPage.getHtmlContent();
+ expect(
+ `
-` );
+`
+ ).toBe( html.toLowerCase() );
// Remove list block to reset editor to clean state
- listBlockElement = await editorPage.getBlockAtPosition( listBlockName );
+ listBlockElement = await editorPage.getBlockAtPosition(
+ blockNames.list
+ );
await listBlockElement.click();
- await editorPage.removeBlockAtPosition( listBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.list );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js
index 7b6aed2b2266c3..115a849df3df61 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Spacer Block test', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const moreBlockName = 'More';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add an separator block', async () => {
- await editorPage.addNewBlock( moreBlockName );
+ await editorPage.addNewBlock( blockNames.more );
const separatorBlock = await editorPage.getBlockAtPosition(
- moreBlockName
+ blockNames.more
);
expect( separatorBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( moreBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.more );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js
index d7ca8fa0e32b70..f6ab1e191fc541 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js
@@ -1,50 +1,20 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
+import { blockNames } from './pages/editor-page';
import {
backspace,
- setupDriver,
- isLocalEnvironment,
clickMiddleOfElement,
clickBeginningOfElement,
- stopDriver,
isAndroid,
} from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests for Paragraph Block', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const paragraphBlockName = 'Paragraph';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a new Paragraph block', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -54,13 +24,13 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
paragraphBlockElement,
testData.shortText
);
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
} );
it( 'should be able to split one paragraph block into two', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -73,15 +43,21 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
const textViewElement = await editorPage.getTextViewForParagraphBlock(
paragraphBlockElement
);
- await clickMiddleOfElement( driver, textViewElement );
+ await clickMiddleOfElement( editorPage.driver, textViewElement );
await editorPage.typeTextToParagraphBlock(
paragraphBlockElement,
'\n',
false
);
expect(
- ( await editorPage.hasBlockAtPosition( 1, paragraphBlockName ) ) &&
- ( await editorPage.hasBlockAtPosition( 2, paragraphBlockName ) )
+ ( await editorPage.hasBlockAtPosition(
+ 1,
+ blockNames.paragraph
+ ) ) &&
+ ( await editorPage.hasBlockAtPosition(
+ 2,
+ blockNames.paragraph
+ ) )
).toBe( true );
const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 );
@@ -92,14 +68,14 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
new RegExp( `${ text0 + text1 }|${ text0 } ${ text1 }` )
);
- await editorPage.removeBlockAtPosition( paragraphBlockName, 2 );
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph, 2 );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
} );
it( 'should be able to merge 2 paragraph blocks into 1', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
let paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -112,20 +88,26 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
let textViewElement = await editorPage.getTextViewForParagraphBlock(
paragraphBlockElement
);
- await clickMiddleOfElement( driver, textViewElement );
+ await clickMiddleOfElement( editorPage.driver, textViewElement );
await editorPage.typeTextToParagraphBlock(
paragraphBlockElement,
'\n'
);
expect(
- ( await editorPage.hasBlockAtPosition( 1, paragraphBlockName ) ) &&
- ( await editorPage.hasBlockAtPosition( 2, paragraphBlockName ) )
+ ( await editorPage.hasBlockAtPosition(
+ 1,
+ blockNames.paragraph
+ ) ) &&
+ ( await editorPage.hasBlockAtPosition(
+ 2,
+ blockNames.paragraph
+ ) )
).toBe( true );
const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 );
const text1 = await editorPage.getTextForParagraphBlockAtPosition( 2 );
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
if ( isAndroid() ) {
@@ -135,7 +117,7 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
textViewElement = await editorPage.getTextViewForParagraphBlock(
paragraphBlockElement
);
- await clickBeginningOfElement( driver, textViewElement );
+ await clickBeginningOfElement( editorPage.driver, textViewElement );
await editorPage.typeTextToParagraphBlock(
paragraphBlockElement,
backspace
@@ -145,15 +127,15 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
expect( text0 + text1 ).toMatch( text );
expect(
- await editorPage.hasBlockAtPosition( 2, paragraphBlockName )
+ await editorPage.hasBlockAtPosition( 2, blockNames.paragraph )
).toBe( false );
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
} );
it( 'should be able to create a post with multiple paragraph blocks', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -162,7 +144,7 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
await editorPage.sendTextToParagraphBlock( 1, testData.longText );
for ( let i = 3; i > 0; i-- ) {
- await editorPage.removeBlockAtPosition( paragraphBlockName, i );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph, i );
}
} );
@@ -180,11 +162,11 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
// // Merge paragraphs
const secondParagraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
await clickBeginningOfElement(
- driver,
+ editorPage.driver,
secondParagraphBlockElement
);
await editorPage.typeTextToParagraphBlock(
@@ -198,7 +180,7 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
);
expect( text.length ).not.toEqual( 0 );
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
} );
// Based on https://github.com/wordpress-mobile/gutenberg-mobile/pull/1507
@@ -214,11 +196,11 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
// // Merge paragraphs
const secondParagraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
await clickBeginningOfElement(
- driver,
+ editorPage.driver,
secondParagraphBlockElement
);
await editorPage.typeTextToParagraphBlock(
@@ -232,14 +214,7 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => {
);
expect( text.length ).not.toEqual( 0 );
- await editorPage.removeBlockAtPosition( paragraphBlockName );
+ await editorPage.removeBlockAtPosition( blockNames.paragraph );
} );
}
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
- } );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js
index e79dc67494e970..95c94efebaefcc 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js
@@ -1,54 +1,33 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
+import { blockNames } from './pages/editor-page';
import {
- setupDriver,
- isLocalEnvironment,
longPressMiddleOfElement,
tapSelectAllAboveElement,
tapCopyAboveElement,
tapPasteAboveElement,
- stopDriver,
isAndroid,
} from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor paste tests', () => {
// skip iOS for now
if ( ! isAndroid() ) {
- it( 'skips the tests on any platform other than Android', async () => {} );
+ it( 'skips the tests on any platform other than Android', async () => {
+ expect( true ).toBe( true );
+ } );
return;
}
- let driver;
- let editorPage;
- let allPassed = true;
- const paragraphBlockName = 'Paragraph';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
beforeAll( async () => {
- driver = await setupDriver();
- await driver.setClipboard( '', 'plaintext' );
- editorPage = new EditorPage( driver );
+ await editorPage.driver.setClipboard( '', 'plaintext' );
} );
it( 'copies plain text from one paragraph block and pastes in another', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -63,18 +42,18 @@ describe( 'Gutenberg Editor paste tests', () => {
);
// copy content to clipboard
- await longPressMiddleOfElement( driver, textViewElement );
- await tapSelectAllAboveElement( driver, textViewElement );
- await tapCopyAboveElement( driver, textViewElement );
+ await longPressMiddleOfElement( editorPage.driver, textViewElement );
+ await tapSelectAllAboveElement( editorPage.driver, textViewElement );
+ await tapCopyAboveElement( editorPage.driver, textViewElement );
// create another paragraph block
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
if ( isAndroid() ) {
// On Andrdoid 10 a new auto-suggestion popup is appearing to let the user paste text recently put in the clipboard. Let's dismiss it.
await editorPage.dismissAndroidClipboardSmartSuggestion();
}
const paragraphBlockElement2 = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
if ( isAndroid() ) {
@@ -86,8 +65,8 @@ describe( 'Gutenberg Editor paste tests', () => {
);
// paste into second paragraph block
- await longPressMiddleOfElement( driver, textViewElement2 );
- await tapPasteAboveElement( driver, textViewElement2 );
+ await longPressMiddleOfElement( editorPage.driver, textViewElement2 );
+ await tapPasteAboveElement( editorPage.driver, textViewElement2 );
const text = await editorPage.getTextForParagraphBlockAtPosition( 2 );
expect( text ).toBe( testData.pastePlainText );
@@ -97,7 +76,7 @@ describe( 'Gutenberg Editor paste tests', () => {
// create paragraph block with styled text by editing html
await editorPage.setHtmlContent( testData.pasteHtmlText );
const paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -108,18 +87,18 @@ describe( 'Gutenberg Editor paste tests', () => {
);
// copy content to clipboard
- await longPressMiddleOfElement( driver, textViewElement );
- await tapSelectAllAboveElement( driver, textViewElement );
- await tapCopyAboveElement( driver, textViewElement );
+ await longPressMiddleOfElement( editorPage.driver, textViewElement );
+ await tapSelectAllAboveElement( editorPage.driver, textViewElement );
+ await tapCopyAboveElement( editorPage.driver, textViewElement );
// create another paragraph block
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
if ( isAndroid() ) {
// On Andrdoid 10 a new auto-suggestion popup is appearing to let the user paste text recently put in the clipboard. Let's dismiss it.
await editorPage.dismissAndroidClipboardSmartSuggestion();
}
const paragraphBlockElement2 = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
if ( isAndroid() ) {
@@ -131,17 +110,13 @@ describe( 'Gutenberg Editor paste tests', () => {
);
// paste into second paragraph block
- await longPressMiddleOfElement( driver, textViewElement2 );
- await tapPasteAboveElement( driver, textViewElement2 );
+ await longPressMiddleOfElement( editorPage.driver, textViewElement2 );
+ await tapPasteAboveElement( editorPage.driver, textViewElement2 );
// check styled text by verifying html contents
- await editorPage.verifyHtmlContent( testData.pasteHtmlTextResult );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ const html = await editorPage.getHtmlContent();
+ expect( testData.pasteHtmlTextResult.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js
index 85e426aa5dff3f..8e6c960f299cfc 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js
@@ -1,48 +1,15 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import {
- setupDriver,
- isLocalEnvironment,
- stopDriver,
- isAndroid,
- toggleOrientation,
-} from './helpers/utils';
+import { blockNames } from './pages/editor-page';
+import { isAndroid, toggleOrientation } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor tests', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const paragraphBlockName = 'Paragraph';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add blocks , rotate device and continue adding blocks', async () => {
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
let paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName
+ blockNames.paragraph
);
if ( isAndroid() ) {
await paragraphBlockElement.click();
@@ -53,26 +20,26 @@ describe( 'Gutenberg Editor tests', () => {
testData.mediumText
);
- await toggleOrientation( driver );
+ await toggleOrientation( editorPage.driver );
// On Android the keyboard hides the add block button, let's hide it after rotation
if ( isAndroid() ) {
- await driver.hideDeviceKeyboard();
+ await editorPage.driver.hideDeviceKeyboard();
}
- await editorPage.addNewBlock( paragraphBlockName );
+ await editorPage.addNewBlock( blockNames.paragraph );
if ( isAndroid() ) {
- await driver.hideDeviceKeyboard();
+ await editorPage.driver.hideDeviceKeyboard();
}
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
while ( ! paragraphBlockElement ) {
- await driver.hideDeviceKeyboard();
+ await editorPage.driver.hideDeviceKeyboard();
paragraphBlockElement = await editorPage.getBlockAtPosition(
- paragraphBlockName,
+ blockNames.paragraph,
2
);
}
@@ -80,15 +47,11 @@ describe( 'Gutenberg Editor tests', () => {
paragraphBlockElement,
testData.mediumText
);
- await toggleOrientation( driver );
-
- await editorPage.verifyHtmlContent( testData.deviceRotationHtml );
- } );
+ await toggleOrientation( editorPage.driver );
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ const html = await editorPage.getHtmlContent();
+ expect( testData.deviceRotationHtml.toLowerCase() ).toBe(
+ html.toLowerCase()
+ );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js
index 438e1a5c1c9c5b..34c0551bcbd464 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Separator Block test', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const separatorBlockName = 'Separator';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add an separator block', async () => {
- await editorPage.addNewBlock( separatorBlockName );
+ await editorPage.addNewBlock( blockNames.separator );
const separatorBlock = await editorPage.getBlockAtPosition(
- separatorBlockName
+ blockNames.separator
);
expect( separatorBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( separatorBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.separator );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js
index 2aa09cc523bb15..febd3fb8f6d81e 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Spacer Block test', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const spacerBlockName = 'Spacer';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add an separator block', async () => {
- await editorPage.addNewBlock( spacerBlockName );
+ await editorPage.addNewBlock( blockNames.spacer );
const separatorBlock = await editorPage.getBlockAtPosition(
- spacerBlockName
+ blockNames.spacer
);
expect( separatorBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( spacerBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.spacer );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-unsupported-blocks.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-unsupported-blocks.test.js
index 3a1dc715cf44a5..6e1be2a13dddb6 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-unsupported-blocks.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-unsupported-blocks.test.js
@@ -1,37 +1,9 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
import testData from './helpers/test-data';
-jest.setTimeout( 1000000 );
-
describe( 'Gutenberg Editor Unsupported Block Editor Tests', () => {
- let driver;
- let editorPage;
- let allPassed = true;
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to open the unsupported block web view editor', async () => {
await editorPage.setHtmlContent( testData.unsupportedBlockHtml );
@@ -48,11 +20,4 @@ describe( 'Gutenberg Editor Unsupported Block Editor Tests', () => {
editorPage.getUnsupportedBlockWebView()
).resolves.toBeTruthy();
} );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
- } );
} );
diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js
index bc8412a3ee832f..93068088f84896 100644
--- a/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js
+++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js
@@ -1,51 +1,16 @@
/**
* Internal dependencies
*/
-import EditorPage from './pages/editor-page';
-import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils';
-
-jest.setTimeout( 1000000 );
+import { blockNames } from './pages/editor-page';
describe( 'Gutenberg Editor Verse Block Tests', () => {
- let driver;
- let editorPage;
- let allPassed = true;
- const verseBlockName = 'Verse';
-
- // Use reporter for setting status for saucelabs Job
- if ( ! isLocalEnvironment() ) {
- const reporter = {
- specDone: async ( result ) => {
- allPassed = allPassed && result.status !== 'failed';
- },
- };
-
- jasmine.getEnv().addReporter( reporter );
- }
-
- beforeAll( async () => {
- driver = await setupDriver();
- editorPage = new EditorPage( driver );
- } );
-
- it( 'should be able to see visual editor', async () => {
- await expect( editorPage.getBlockList() ).resolves.toBe( true );
- } );
-
it( 'should be able to add a verse block', async () => {
- await editorPage.addNewBlock( verseBlockName );
+ await editorPage.addNewBlock( blockNames.verse );
const verseBlock = await editorPage.getBlockAtPosition(
- verseBlockName
+ blockNames.verse
);
expect( verseBlock ).toBeTruthy();
- await editorPage.removeBlockAtPosition( verseBlockName );
- } );
-
- afterAll( async () => {
- if ( ! isLocalEnvironment() ) {
- driver.sauceJobStatus( allPassed );
- }
- await stopDriver( driver );
+ await editorPage.removeBlockAtPosition( blockNames.verse );
} );
} );
diff --git a/packages/react-native-editor/__device-tests__/helpers/appium-local.js b/packages/react-native-editor/__device-tests__/helpers/appium-local.js
index 71a0cd44aea18b..be44a83f83f6ae 100644
--- a/packages/react-native-editor/__device-tests__/helpers/appium-local.js
+++ b/packages/react-native-editor/__device-tests__/helpers/appium-local.js
@@ -1,10 +1,10 @@
/**
* External dependencies
*/
-import childProcess from 'child_process';
+const childProcess = require( 'child_process' );
// Spawns an appium process
-export const start = ( localAppiumPort ) =>
+const start = ( localAppiumPort ) =>
new Promise( ( resolve, reject ) => {
const appium = childProcess.spawn( 'appium', [
'--port',
@@ -40,14 +40,14 @@ export const start = ( localAppiumPort ) =>
} );
} );
-export const stop = async ( appium ) => {
+const stop = async ( appium ) => {
if ( ! appium ) {
return;
}
await appium.kill( 'SIGINT' );
};
-export default {
+module.exports = {
start,
stop,
};
diff --git a/packages/react-native-editor/__device-tests__/helpers/caps.js b/packages/react-native-editor/__device-tests__/helpers/caps.js
index 7f93b87eb07cb3..804ef802fb5c48 100644
--- a/packages/react-native-editor/__device-tests__/helpers/caps.js
+++ b/packages/react-native-editor/__device-tests__/helpers/caps.js
@@ -13,7 +13,6 @@ const ios = {
exports.iosLocal = {
...ios,
- platformVersion: '14.0',
deviceName: 'iPhone 11',
};
diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js
index 7f45e747a22ada..b298c390eb0f0d 100644
--- a/packages/react-native-editor/__device-tests__/helpers/utils.js
+++ b/packages/react-native-editor/__device-tests__/helpers/utils.js
@@ -1,21 +1,19 @@
/**
* External dependencies
*/
-import childProcess from 'child_process';
+const childProcess = require( 'child_process' );
// eslint-disable-next-line import/no-extraneous-dependencies
-import wd from 'wd';
-import crypto from 'crypto';
-import path from 'path';
-import fs from 'fs';
-
+const wd = require( 'wd' );
+const crypto = require( 'crypto' );
+const path = require( 'path' );
/**
* Internal dependencies
*/
-import serverConfigs from './serverConfigs';
-import { iosServer, iosLocal, android } from './caps';
-import AppiumLocal from './appium-local';
+const serverConfigs = require( './serverConfigs' );
+const { iosServer, iosLocal, android } = require( './caps' );
+const AppiumLocal = require( './appium-local' );
// eslint-disable-next-line import/no-extraneous-dependencies
-import _ from 'underscore';
+const _ = require( 'underscore' );
// Platform setup
const defaultPlatform = 'android';
@@ -37,8 +35,6 @@ const localIOSAppPath = process.env.IOS_APP_PATH || defaultIOSAppPath;
const localAppiumPort = serverConfigs.local.port; // Port to spawn appium process for local runs
let appiumProcess;
-let iOSScreenRecordingProcess;
-let androidScreenRecordingProcess;
const backspace = '\u0008';
@@ -59,119 +55,6 @@ const isLocalEnvironment = () => {
return testEnvironment.toLowerCase() === 'local';
};
-const isMacOSEnvironment = () => {
- return process.platform === 'darwin';
-};
-
-const IOS_RECORDINGS_DIR = './ios-screen-recordings';
-const ANDROID_RECORDINGS_DIR = './android-screen-recordings';
-
-const getScreenRecordingFileNameBase = ( testPath, id ) => {
- const suiteName = path.basename( testPath, '.test.js' );
- return `${ suiteName }.${ id }`;
-};
-
-jasmine.getEnv().addReporter( {
- specStarted: ( { testPath, id } ) => {
- if ( ! isMacOSEnvironment() ) {
- return;
- }
-
- const fileName =
- getScreenRecordingFileNameBase( testPath, id ) + '.mp4';
-
- if ( isAndroid() ) {
- if ( ! fs.existsSync( ANDROID_RECORDINGS_DIR ) ) {
- fs.mkdirSync( ANDROID_RECORDINGS_DIR );
- }
-
- androidScreenRecordingProcess = childProcess.spawn( 'adb', [
- 'shell',
- 'screenrecord',
- '--verbose',
- '--bit-rate',
- '1M',
- '--size',
- '720x1280',
- `/sdcard/${ fileName }`,
- ] );
-
- androidScreenRecordingProcess.stderr.on( 'data', ( data ) => {
- // eslint-disable-next-line no-console
- console.log( `Android screen recording error => ${ data }` );
- } );
-
- return;
- }
-
- if ( ! fs.existsSync( IOS_RECORDINGS_DIR ) ) {
- fs.mkdirSync( IOS_RECORDINGS_DIR );
- }
-
- iOSScreenRecordingProcess = childProcess.spawn(
- 'xcrun',
- [
- 'simctl',
- 'io',
- 'booted',
- 'recordVideo',
- '--mask=black',
- '--force',
- fileName,
- ],
- {
- cwd: IOS_RECORDINGS_DIR,
- }
- );
- },
- specDone: ( { testPath, id, status } ) => {
- if ( ! isMacOSEnvironment() ) {
- return;
- }
-
- const fileNameBase = getScreenRecordingFileNameBase( testPath, id );
-
- if ( isAndroid() ) {
- androidScreenRecordingProcess.kill( 'SIGINT' );
- // wait for kill
- childProcess.execSync( 'sleep 1' );
-
- try {
- childProcess.execSync(
- `adb pull /sdcard/${ fileNameBase }.mp4 ${ ANDROID_RECORDINGS_DIR }`
- );
- } catch ( error ) {
- // Some (old) Android devices don't support screen recording or
- // sometimes the initial `should be able to see visual editor`
- // tests are too fast and a recording is not generated. This is
- // when `adb pull` can't find the recording file. In these cases
- // we ignore the errors and keep running the tests.
- // eslint-disable-next-line no-console
- console.log(
- `Android screen recording error => ${ error.stdout }`
- );
- }
-
- const oldPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.mp4`;
- const newPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`;
-
- if ( fs.existsSync( oldPath ) ) {
- fs.renameSync( oldPath, newPath );
- }
- return;
- }
-
- iOSScreenRecordingProcess.kill( 'SIGINT' );
-
- const oldPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.mp4`;
- const newPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`;
-
- if ( fs.existsSync( oldPath ) ) {
- fs.renameSync( oldPath, newPath );
- }
- },
-} );
-
// Initialises the driver and desired capabilities for appium
const setupDriver = async () => {
const branch = process.env.CIRCLE_BRANCH || '';
diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js
index 91c54fc9e190d0..2b08b695935b6a 100644
--- a/packages/react-native-editor/__device-tests__/pages/editor-page.js
+++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js
@@ -1,16 +1,23 @@
/**
* Internal dependencies
*/
-import {
+const {
+ setupDriver,
+ stopDriver,
isAndroid,
swipeUp,
swipeDown,
typeString,
toggleHtmlMode,
swipeFromTo,
-} from '../helpers/utils';
+} = require( '../helpers/utils' );
-export default class EditorPage {
+const initializeEditorPage = async () => {
+ const driver = await setupDriver();
+ return new EditorPage( driver );
+};
+
+class EditorPage {
driver;
accessibilityIdKey;
accessibilityIdXPathAttrib;
@@ -130,16 +137,16 @@ export default class EditorPage {
return await this.driver.elementByXPath( blockLocator );
}
- // Converts to lower case and checks for a match to lowercased html content
+ // Returns html content
// Ensure to take additional steps to handle text being changed by auto correct
- async verifyHtmlContent( html ) {
+ async getHtmlContent() {
await toggleHtmlMode( this.driver, true );
const htmlContentView = await this.getTextViewForHtmlViewContent();
const text = await htmlContentView.text();
- expect( text.toLowerCase() ).toBe( html.toLowerCase() );
await toggleHtmlMode( this.driver, false );
+ return text;
}
// set html editor content explicitly
@@ -536,4 +543,30 @@ export default class EditorPage {
this.driver.setImplicitWaitTimeout( 5000 );
return element;
}
+
+ async stopDriver() {
+ await stopDriver( this.driver );
+ }
+
+ async sauceJobStatus( allPassed ) {
+ await this.driver.sauceJobStatus( allPassed );
+ }
}
+
+const blockNames = {
+ paragraph: 'Paragraph',
+ gallery: 'Gallery',
+ columns: 'Columns',
+ cover: 'Cover',
+ heading: 'Heading',
+ image: 'Image',
+ latestPosts: 'Latest Posts',
+ list: 'List',
+ more: 'More',
+ separator: 'Separator',
+ spacer: 'Spacer',
+ verse: 'Verse',
+ file: 'File',
+};
+
+module.exports = { initializeEditorPage, blockNames };
diff --git a/test/native/jest_ui.config.js b/packages/react-native-editor/jest_ui.config.js
similarity index 79%
rename from test/native/jest_ui.config.js
rename to packages/react-native-editor/jest_ui.config.js
index 15855a1a261e0b..fbbb9f7ff89208 100644
--- a/test/native/jest_ui.config.js
+++ b/packages/react-native-editor/jest_ui.config.js
@@ -10,7 +10,7 @@ if ( process.env.TEST_RN_PLATFORM ) {
module.exports = {
verbose: true,
- rootDir: '../../',
+ rootDir: './',
haste: {
defaultPlatform: rnPlatform,
platforms: [ 'android', 'ios', 'native' ],
@@ -19,6 +19,8 @@ module.exports = {
'^.+\\.(js|ts|tsx)$': 'babel-jest',
},
timers: 'real',
- setupFiles: [],
+ setupFilesAfterEnv: [ './jest_ui_setup_after_env.js' ],
+ testEnvironment: './jest_ui_test_environment.js',
testMatch: [ '**/__device-tests__/**/*.test.[jt]s?(x)' ],
+ reporters: [ 'default', 'jest-junit' ],
};
diff --git a/packages/react-native-editor/jest_ui_setup_after_env.js b/packages/react-native-editor/jest_ui_setup_after_env.js
new file mode 100644
index 00000000000000..3f90091bf77552
--- /dev/null
+++ b/packages/react-native-editor/jest_ui_setup_after_env.js
@@ -0,0 +1,146 @@
+/**
+ * External dependencies
+ */
+const fs = require( 'fs' );
+const path = require( 'path' );
+const childProcess = require( 'child_process' );
+
+/**
+ * Internal dependencies
+ */
+const {
+ isAndroid,
+ isLocalEnvironment,
+} = require( './__device-tests__/helpers/utils' );
+
+jest.setTimeout( 1000000 ); // in milliseconds
+
+let iOSScreenRecordingProcess;
+let androidScreenRecordingProcess;
+
+const isMacOSEnvironment = () => {
+ return process.platform === 'darwin';
+};
+
+const IOS_RECORDINGS_DIR = './ios-screen-recordings';
+const ANDROID_RECORDINGS_DIR = './android-screen-recordings';
+
+const getScreenRecordingFileNameBase = ( testPath, id ) => {
+ const suiteName = path.basename( testPath, '.test.js' );
+ return `${ suiteName }.${ id }`;
+};
+
+let allPassed = true;
+
+jasmine.getEnv().addReporter( {
+ specStarted: ( { testPath, id } ) => {
+ if ( ! isMacOSEnvironment() ) {
+ return;
+ }
+
+ const fileName =
+ getScreenRecordingFileNameBase( testPath, id ) + '.mp4';
+
+ if ( isAndroid() ) {
+ if ( ! fs.existsSync( ANDROID_RECORDINGS_DIR ) ) {
+ fs.mkdirSync( ANDROID_RECORDINGS_DIR );
+ }
+
+ androidScreenRecordingProcess = childProcess.spawn( 'adb', [
+ 'shell',
+ 'screenrecord',
+ '--verbose',
+ '--bit-rate',
+ '1M',
+ '--size',
+ '720x1280',
+ `/sdcard/${ fileName }`,
+ ] );
+
+ androidScreenRecordingProcess.stderr.on( 'data', ( data ) => {
+ // eslint-disable-next-line no-console
+ console.log( `Android screen recording error => ${ data }` );
+ } );
+
+ return;
+ }
+
+ if ( ! fs.existsSync( IOS_RECORDINGS_DIR ) ) {
+ fs.mkdirSync( IOS_RECORDINGS_DIR );
+ }
+
+ iOSScreenRecordingProcess = childProcess.spawn(
+ 'xcrun',
+ [
+ 'simctl',
+ 'io',
+ 'booted',
+ 'recordVideo',
+ '--mask=black',
+ '--force',
+ fileName,
+ ],
+ {
+ cwd: IOS_RECORDINGS_DIR,
+ }
+ );
+ },
+ specDone: ( { testPath, id, status } ) => {
+ allPassed = allPassed && status !== 'failed';
+
+ if ( ! isMacOSEnvironment() ) {
+ return;
+ }
+
+ const fileNameBase = getScreenRecordingFileNameBase( testPath, id );
+
+ if ( isAndroid() ) {
+ androidScreenRecordingProcess.kill( 'SIGINT' );
+ // wait for kill
+ childProcess.execSync( 'sleep 1' );
+
+ try {
+ childProcess.execSync(
+ `adb pull /sdcard/${ fileNameBase }.mp4 ${ ANDROID_RECORDINGS_DIR }`
+ );
+ } catch ( error ) {
+ // Some (old) Android devices don't support screen recording or
+ // sometimes the initial `should be able to see visual editor`
+ // tests are too fast and a recording is not generated. This is
+ // when `adb pull` can't find the recording file. In these cases
+ // we ignore the errors and keep running the tests.
+ // eslint-disable-next-line no-console
+ console.log(
+ `Android screen recording error => ${ error.stdout }`
+ );
+ }
+
+ const oldPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.mp4`;
+ const newPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`;
+
+ if ( fs.existsSync( oldPath ) ) {
+ fs.renameSync( oldPath, newPath );
+ }
+ return;
+ }
+
+ iOSScreenRecordingProcess.kill( 'SIGINT' );
+
+ const oldPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.mp4`;
+ const newPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`;
+
+ if ( fs.existsSync( oldPath ) ) {
+ fs.renameSync( oldPath, newPath );
+ }
+ },
+ suiteDone() {
+ if ( ! isLocalEnvironment() ) {
+ global.editorPage.sauceJobStatus( allPassed );
+ }
+ },
+} );
+
+it( 'should be able to see visual editor', async () => {
+ // wait for the block editor to load
+ await expect( global.editorPage.getBlockList() ).resolves.toBe( true );
+} );
diff --git a/packages/react-native-editor/jest_ui_test_environment.js b/packages/react-native-editor/jest_ui_test_environment.js
new file mode 100644
index 00000000000000..052aa95da0781f
--- /dev/null
+++ b/packages/react-native-editor/jest_ui_test_environment.js
@@ -0,0 +1,26 @@
+/**
+ * Internal dependencies
+ */
+const {
+ initializeEditorPage,
+} = require( './__device-tests__/pages/editor-page' );
+
+/**
+ * External dependencies
+ */
+// eslint-disable-next-line import/no-extraneous-dependencies
+const JSDOMEnvironment = require( 'jest-environment-jsdom' );
+
+class CustomEnvironment extends JSDOMEnvironment {
+ async setup() {
+ await super.setup();
+ this.global.editorPage = await initializeEditorPage();
+ }
+
+ async teardown() {
+ await this.global.editorPage.stopDriver();
+ await super.teardown();
+ }
+}
+
+module.exports = CustomEnvironment;
diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json
index 0573d9b47c2a8a..a6c0fc85810aaa 100644
--- a/packages/react-native-editor/package.json
+++ b/packages/react-native-editor/package.json
@@ -102,10 +102,10 @@
"ios:fast": "react-native run-ios",
"test": "cross-env NODE_ENV=test jest --verbose --config ../../test/native/jest.config.js",
"test:debug": "cross-env NODE_ENV=test node --inspect-brk jest --runInBand --verbose --config ../../test/native/jest.config.js",
- "device-tests": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=3 --reporters=default --reporters=jest-junit --verbose --config ../../test/native/jest_ui.config.js",
- "device-tests-canary": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=2 --testNamePattern=@canary --reporters=default --reporters=jest-junit --verbose --config ../../test/native/jest_ui.config.js",
- "device-tests:local": "cross-env NODE_ENV=test jest --runInBand --reporters=default --reporters=jest-junit --detectOpenHandles --verbose --forceExit --config ../../test/native/jest_ui.config.js",
- "device-tests:debug": "cross-env NODE_ENV=test node $NODE_DEBUG_OPTION --inspect-brk node_modules/jest/bin/jest --runInBand --reporters=default --reporters=jest-junit --detectOpenHandles --verbose --config ../../test/native/jest_ui.config.js",
+ "device-tests": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=3 --verbose --config ./jest_ui.config.js",
+ "device-tests-canary": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=2 --testNamePattern=@canary --verbose --config ./jest_ui.config.js",
+ "device-tests:local": "cross-env NODE_ENV=test jest --runInBand --detectOpenHandles --verbose --forceExit --config ./jest_ui.config.js",
+ "device-tests:debug": "cross-env NODE_ENV=test node $NODE_DEBUG_OPTION --inspect-brk node_modules/jest/bin/jest --runInBand --detectOpenHandles --verbose --config ./jest_ui.config.js",
"test:e2e:bundle:android": "mkdir -p android/app/src/main/assets && npm run rn-bundle -- --reset-cache --platform android --dev false --minify false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
"test:e2e:build-app:android": "cd android && ./gradlew clean && ./gradlew assembleDebug",
"test:e2e:android:local": "npm run test:e2e:bundle:android && npm run test:e2e:build-app:android && TEST_RN_PLATFORM=android npm run device-tests:local",