Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
74f8072
Add a build file for running smoke tests
tiny-ben-tran Feb 11, 2026
25f4da9
Install next angular version
tiny-ben-tran Feb 11, 2026
fb3c060
Fix command
tiny-ben-tran Feb 11, 2026
934797c
Add smoketest file
tiny-ben-tran Feb 13, 2026
a5fa379
Update the test script to run browser tests only
tiny-ben-tran Feb 13, 2026
9d34d34
Add a smoke-test bash script file
tiny-ben-tran Feb 15, 2026
2a3b94c
Update jenkins smoke test file
tiny-ben-tran Feb 16, 2026
57d3098
Fix jenkin errors
tiny-ben-tran Feb 16, 2026
12575f1
Log messages
tiny-ben-tran Feb 16, 2026
da57e4b
Add the missing parall process
tiny-ben-tran Feb 16, 2026
76f26f8
Try firefox
tiny-ben-tran Feb 16, 2026
abf48b1
Use remote command
tiny-ben-tran Feb 16, 2026
e57f0c8
Fix syntax
tiny-ben-tran Feb 16, 2026
6a6c418
Add missing browser
tiny-ben-tran Feb 16, 2026
095fc15
Move bashcript into jenkinsfile
tiny-ben-tran Feb 18, 2026
07e31c3
Fix errors
tiny-ben-tran Feb 18, 2026
3700ef9
More fixes
tiny-ben-tran Feb 18, 2026
2622164
Use workspace
tiny-ben-tran Feb 18, 2026
6a5bb32
Use double quotes where interpolation is required
tiny-ben-tran Feb 18, 2026
b6ebd98
Fix string
tiny-ben-tran Feb 18, 2026
71c5dc7
Preserve double quotes in json format
tiny-ben-tran Feb 18, 2026
7d8c46b
Use JSON utility functions to handle json
tiny-ben-tran Feb 18, 2026
9e928ed
Enable tests on more platforms
tiny-ben-tran Feb 18, 2026
7ece6dc
Reduce the number of times of installing the upcoming release
tiny-ben-tran Feb 18, 2026
f589733
Fix variable not defined
tiny-ben-tran Feb 18, 2026
3e1d8a4
Move build target
tiny-ben-tran Feb 18, 2026
ccec3a3
Fix custom route file not found
tiny-ben-tran Feb 18, 2026
709c5b3
Fix workspace error
tiny-ben-tran Feb 18, 2026
daa19e3
try again
tiny-ben-tran Feb 18, 2026
c8aa14b
Install dependencies on each browser test
tiny-ben-tran Feb 18, 2026
1d9b70e
Revert previous changes
tiny-ben-tran Feb 18, 2026
9cd6a37
Refactor
tiny-ben-tran Feb 19, 2026
941ecd9
Default NPM_TAG param
tiny-ben-tran Feb 19, 2026
3b42bba
Again
tiny-ben-tran Feb 19, 2026
90d3e0a
more changes
tiny-ben-tran Feb 19, 2026
7aef68b
Fix test directory not found
tiny-ben-tran Feb 19, 2026
9665a0f
Echo the target framework version
tiny-ben-tran Feb 19, 2026
c32332d
Clean up
tiny-ben-tran Feb 19, 2026
5d9eaac
Fix lint errors
tiny-ben-tran Feb 19, 2026
66111d0
Stop running a node inside another node
tiny-ben-tran Feb 19, 2026
439dd7c
More improvements
tiny-ben-tran Feb 19, 2026
4f618dd
Fix node context issue
tiny-ben-tran Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions Jenkinsfile-SmokeTest
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!groovy
@Library('waluigi@release/7') _

properties([
disableConcurrentBuilds(),
buildDiscarder(logRotator(
artifactDaysToKeepStr: '',
artifactNumToKeepStr: '1',
daysToKeepStr: '',
numToKeepStr: '50'
)),
parameters([
string(defaultValue: 'next', description: 'The NPM publish tag ', name: 'NPM_TAG', trim: false),
])
])

// Generates a custom route file that contains the next version of Angular to test against
def generateNPMVersionRouteFile(Map args = new LinkedHashMap()) {
// @angular/core's version is the one baked into the angular app
def nextVersion = sh(script: "npm view @angular/core@${args.npm_tag} version", returnStdout: true).trim()

echo "Target framework version: ${nextVersion}"

def routeFileContent = readJSON text: """
[{
"request": {
"method": "get",
"path": "/custom/integration/info"
},
"response": {
"status": 200,
"json": {
"version": "${nextVersion}"
}
}
}]
"""
writeJSON file: "${args.filePath}", json: routeFileContent
}

// Updates the Angular dependencies to the version specified by the npm tag
def updateDependenciesWithTag(Map args = new LinkedHashMap()) {
String npm_tag = args.npm_tag
sh "yarn add @angular/core@${npm_tag} @angular/animations@${npm_tag} @angular/common@${npm_tag} @angular/compiler@${npm_tag} @angular/core@${npm_tag} @angular/forms@${npm_tag} @angular/platform-browser@${npm_tag} @angular-devkit/build-angular@${npm_tag} @angular/cli@${npm_tag} @angular/compiler-cli@${npm_tag}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's one way of doing it, I guess 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could be made easier/nicer if ng update command could resolve with private/local packages ie: tinymce-4, tinymce-5, etc. At the moment, it just throws not found error because it tries to fetch the packages from NPM

}

def runSmokeTests(Map args = new LinkedHashMap()) {
def platforms = args.platforms ?: [
[ browser: "chrome", provider: "lambdatest" ]
]
String customRouteFilePath = "${WORKSPACE}/version.json"
String additionalArgs = "--chunk 20 --totalTimeout 1800000 --singleTimeout 90000 --retries 3 --customRoutes ${customRouteFilePath}"

def processes = [:]

for (int i = 0; i < platforms.size(); i++) {
def platform = platforms.get(i)
def buckets = platform.buckets ?: 1

for (int bucket = 1; bucket <= buckets; bucket++) {
// clousure var - don't inline or jenkins complains
def currBucket = bucket
def suffix = currBucket == 1 ? '' : "-${currBucket}"

// Run using remote provider
if (platform.provider) {
def name = "${platform.browser}-${platform.provider}${suffix}"
processes[name] = {
stage("${name}") {
bedrockRemoteTools.tinyWorkSishTunnel()
bedrockRemoteTools.withRemoteCreds(platform.provider) {
String customArgs = additionalArgs + " --remote ${platform.provider}"
if (platform.provider == "aws") {
customArgs = customArgs + " --sishDomain \"sish.osu.tiny.work\""
}
if (platform.os) {
customArgs = customArgs + " --platformName \"${platform.os}\""
}

generateNPMVersionRouteFile(npm_tag: args.npm_tag, filePath: customRouteFilePath)
updateDependenciesWithTag(npm_tag: args.npm_tag)
bedrockTests(
name: name,
browser: platform.browser,
testDirs: [ "tinymce-angular-component/src/test/ts" ],
bucket: currBucket,
buckets: buckets,
custom: customArgs
)
}
}
}
} else {
// Headless code in case is needed
def name = "headless-${platform.browser}${suffix}"
processes[name] = {
stage("${name}") {
generateNPMVersionRouteFile(npm_tag: args.npm_tag, filePath: customRouteFilePath)
updateDependenciesWithTag(npm_tag: args.npm_tag)
bedrockTests(
name: name,
browser: platform.browser,
testDirs: [ "tinymce-angular-component/src/test/ts" ],
bucket: currBucket,
buckets: buckets,
custom: additionalArgs + " --useSelenium"
)
}
}
}
}
}

parallel processes
}

timestamps {
tinyPods.node() {
stage('deps') {
yarnInstall()
}

stage('build') {
sh 'yarn build'
}

stage('tests') {
runSmokeTests(npm_tag: params.NPM_TAG ?: 'latest')
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "MIT",
"scripts": {
"preinstall": "node -e \"if(process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('You must use Yarn to install, not NPM')\"",
"test": "yarn bedrock-auto -b chrome-headless -f tinymce-angular-component/src/test/ts/**/*Test.ts",
"test": "yarn bedrock-auto -b chrome-headless -f tinymce-angular-component/src/test/ts/browser/*Test.ts",
"test-manual": "bedrock -f tinymce-angular-component/src/test/ts/**/*Test.ts",
"clean": "yarn rimraf dist",
"lint": "eslint tinymce-angular-component/src/**/*.ts stories/**/*.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { ScriptLoader } from '../../../main/ts/utils/ScriptLoader';
import { Attribute, Remove, SelectorFilter, SugarElement } from '@ephox/sugar';
import { ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { EditorComponent } from '../../../main/ts/editor/editor.component';
import { EditorComponent, Version } from '../../../main/ts/editor/editor.component';
import type { Editor } from 'tinymce';
import { Keyboard, Keys } from '@ephox/agar';

export const apiKey = Fun.constant('qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc');

export const supportedTinymceVersions = Fun.constant<Version[]>([ '5', '6', '7', '8' ]);

export const throwTimeout =
(timeoutMs: number, message: string = `Timeout ${timeoutMs}ms`) =>
<T>(source: Observable<T>) =>
Expand Down
11 changes: 8 additions & 3 deletions tinymce-angular-component/src/test/ts/alien/TestHooks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { after, before, beforeEach, context } from '@ephox/bedrock-client';
import { ComponentFixture, TestBed, TestModuleMetadata } from '@angular/core/testing';
import { Type } from '@angular/core';
import { Type, VERSION } from '@angular/core';
import { EditorComponent, Version } from '../../../main/ts/editor/editor.component';
import { firstValueFrom, map, switchMap, tap } from 'rxjs';
import { By } from '@angular/platform-browser';
Expand All @@ -9,6 +9,7 @@ import { VersionLoader } from '@tinymce/miniature';
import { deleteTinymce, throwTimeout } from './TestHelpers';
import { FormsModule, ReactiveFormsModule, NgModel } from '@angular/forms';
import type { Editor } from 'tinymce';
import { Attribute, SugarElement } from '@ephox/sugar';

export const fixtureHook = <T = unknown>(component: Type<T>, moduleDef: TestModuleMetadata) => {
before(async () => {
Expand Down Expand Up @@ -69,15 +70,19 @@ export const editorHook = <T = unknown>(component: Type<T>, moduleDef: TestModul
fixture.detectChanges();

return firstValueFrom(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument

editorComponent.onInit.pipe(
throwTimeout(10000, `Timed out waiting for editor to load`),
switchMap(
({ editor }) =>
new Promise<Editor>((resolve) => {
editor.once('SkinLoaded', () => {
// Bake the Angular version as a data attribute on the editor container so it can be verified in the test
const container = editor.getContainer();
Attribute.set(SugarElement.fromDom( container), 'data-framework-version', VERSION.full);

// This is a workaround to avoid a race condition occurring in tinymce 8 where licenseKeyManager is still validating the license key
// after global tinymce is removed in a clean up. Specifically, it happens when unloading/loading different versions of TinyMCE
// after global tinymce is removed in a clean up. Specifically, it happens when unloading/loading different versions of TinyMCE
if (editor.licenseKeyManager) {
editor.licenseKeyManager.validate({}).then(() => {
resolve(editor as Editor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EditorComponent, TINYMCE_SCRIPT_SRC } from '../../../main/ts/public_api
import { Version } from '../../../main/ts/editor/editor.component';
import { editorHook, tinymceVersionHook } from '../alien/TestHooks';
import type { Editor } from 'tinymce';
import { apiKey, deleteTinymce } from '../alien/TestHelpers';
import { apiKey, deleteTinymce, supportedTinymceVersions } from '../alien/TestHelpers';

describe('LoadTinyTest', () => {
const key = apiKey();
Expand All @@ -17,7 +17,7 @@ describe('LoadTinyTest', () => {
Assertions.assertEq(`Loaded version of TinyMCE should be ${version}`, version, Global.tinymce.majorVersion);
};

for (const version of [ '4', '5', '6', '7', '8' ] as Version[]) {
for (const version of supportedTinymceVersions()) {
context(`With local version ${version}`, () => {
const createFixture = editorHook(EditorComponent, {
providers: [
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('LoadTinyTest', () => {
});
}

for (const version of [ '5', '6', '7', '8' ] as Version[]) {
for (const version of supportedTinymceVersions()) {
context(`With cloud version ${version}`, () => {
const createFixture = editorHook(EditorComponent);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import '../alien/InitTestEnvironment';

import { Assertions } from '@ephox/agar';
import { describe, it, context, before } from '@ephox/bedrock-client';
import { Global } from '@ephox/katamari';
import { SugarElement, Attribute } from '@ephox/sugar';

import { EditorComponent, TINYMCE_SCRIPT_SRC } from '../../../main/ts/public_api';
import { Version } from '../../../main/ts/editor/editor.component';
import { editorHook } from '../alien/TestHooks';
import type { Editor } from 'tinymce';
import { deleteTinymce, supportedTinymceVersions } from '../alien/TestHelpers';

/*
This test requires the targeted Angular version provided via custom route
*/
describe('VerifyIntegrationTest', () => {
interface IntegrationInfo {
version: string;
}

const assertTinymceVersion = (version: Version, editor: Editor) => {
Assertions.assertEq(`Loaded version of TinyMCE should be ${version}`, version, editor.editorManager.majorVersion);
Assertions.assertEq(`Loaded version of TinyMCE should be ${version}`, version, Global.tinymce.majorVersion);
};

for (const version of supportedTinymceVersions()) {
context(`With local Tinymce version ${version}`, () => {
const createFixture = editorHook(EditorComponent, {
providers: [
{
provide: TINYMCE_SCRIPT_SRC,
useValue: `/project/node_modules/tinymce-${version}/tinymce.min.js`,
},
],
});

before(deleteTinymce);

it('Should be able to load with the specified Angular version', async () => {
const { editor } = await createFixture();
const integrationInfo = await window.fetch('/custom/integration/info').then((resp) => resp.json()) as IntegrationInfo;
const container = editor.getContainer();

Assertions.assertEq(`Angular version should be ${integrationInfo.version}`,
true,
Attribute.get(SugarElement.fromDom(container), 'data-framework-version') === integrationInfo.version
);

assertTinymceVersion(version, editor);
});
});
}
});
Loading