Skip to content

Commit

Permalink
feat: javascript refactoring with ability to run JS tests in build pr…
Browse files Browse the repository at this point in the history
…ocess (#203)

ExportParams and ExportContext
  • Loading branch information
grigoriev authored Sep 13, 2024
1 parent 3b36210 commit a84ec78
Show file tree
Hide file tree
Showing 12 changed files with 628 additions and 186 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ target/
dependency-reduced-pom.xml

src/main/resources/webapp/*-admin/html/about.html
README.html
README.html

node/
node_modules/
package-lock.json
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"dependencies": {
"micromodal": "^0.4.10"
},
"devDependencies": {
"chai": "^4.3.4",
"mocha": "10.1.0"
},
"name": "maven-js-project",
"scripts": {
"test": "mocha src/test/js/**/*.js"
},
"type": "module",
"version": "1.0.0"
}
45 changes: 44 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
<pdfbox.version>3.0.3</pdfbox.version>
<okapi.xliff.version>1.46.0</okapi.xliff.version>
<byte-buddy.version>1.15.1</byte-buddy.version>
<re2j.version>1.7</re2j.version>

<slf4j.version>1.7.36</slf4j.version>
<testcontainers.version>1.20.1</testcontainers.version>
Expand All @@ -65,6 +64,10 @@
<!--suppress UnresolvedMavenProperty -->
<markdown2html-maven-plugin.failOnError>${env.MARKDOWN2HTML_MAVEN_PLUGIN_FAIL_ON_ERROR}</markdown2html-maven-plugin.failOnError>
<swagger-maven-plugin.version>2.2.22</swagger-maven-plugin.version>

<frontend-maven-plugin.version>1.15.0</frontend-maven-plugin.version>
<frontend-maven-plugin.nodeVersion>v20.17.0</frontend-maven-plugin.nodeVersion>
<frontend-maven-plugin.npmVersion>10.8.3</frontend-maven-plugin.npmVersion>
</properties>

<dependencies>
Expand Down Expand Up @@ -199,6 +202,46 @@
</resourcePackages>
</configuration>
</plugin>

<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<executions>
<execution>
<id>install-node-and-npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>${frontend-maven-plugin.nodeVersion}</nodeVersion>
<npmVersion>${frontend-maven-plugin.npmVersion}</npmVersion>
</configuration>
</execution>

<!-- Install JavaScript dependencies using npm -->
<execution>
<id>npm-install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>

<!-- Run JavaScript tests -->
<execution>
<id>npm-test</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run test</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
public class FileNameTemplateSettings extends GenericNamedSettings<FileNameTemplateModel> {
public static final String FEATURE_NAME = "filename-template";
public static final String DEFAULT_LIVE_DOC_NAME_TEMPLATE = "$projectName $document.moduleNameWithSpace.replace(\" / \", \" \")";
public static final String DEFAULT_LIVE_REPORT_NAME_TEMPLATE = "$projectName $page.pageNameWithSpace.replace(\" / \", \" \") $page.revision";
public static final String DEFAULT_LIVE_REPORT_NAME_TEMPLATE = "$projectName $page.pageNameWithSpace.replace(\" / \", \" \") {{ REVISION }}";
public static final String DEFAULT_TEST_RUN_NAME_TEMPLATE = "$projectName $testrun.label";
public static final String DEFAULT_WIKI_PAGE_NAME_TEMPLATE = "$projectName $page.pageNameWithSpace.replace(\" / \", \" \") $page.revision";
public static final String DEFAULT_WIKI_PAGE_NAME_TEMPLATE = "$projectName $page.pageNameWithSpace.replace(\" / \", \" \") {{ REVISION }}";

public FileNameTemplateSettings() {
super(FEATURE_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ protected void render(@NotNull final HtmlFragmentBuilder builder) {
OpenInTableButtonWidgetRenderer button = new OpenInTableButtonWidgetRenderer("Export to PDF", null, null) {
@Override
protected void configureLinkAttributes(@NotNull HtmlTagBuilder a) {
a.attributes().onClick(builder.target().escapeForAttribute("PdfExporter.openPopup({ context: (new ExportContext().path === 'testrun' ? 'test_run' : 'live_report') })"));
//language=JS
String onClickAction = "PdfExporter.openPopup({ exportContext: new ExportContext(ExportParams.DocumentType.LIVE_REPORT) });";
a.attributes().onClick(builder.target().escapeForAttribute(onClickAction));
}
};
button.render(this.context, builder);
Expand Down
54 changes: 27 additions & 27 deletions src/main/resources/webapp/pdf-exporter/js/export-pdf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const ExportPdf = {
stylePackageChanged: function () {
console.log("stylePackageChanged");
const selectedStylePackage = document.getElementById("style-package-select").value;
const scope = document.querySelector("input[name='scope']").value;
if (selectedStylePackage && scope) {
Expand Down Expand Up @@ -125,32 +124,33 @@ const ExportPdf = {

buildRequestJson: function (projectId, locationPath, selectedChapters, numberedListStyles, selectedRoles) {
const urlSearchParams = new URL(window.location.href.replace('#', '/')).searchParams;
return JSON.stringify({
projectId: projectId,
locationPath: locationPath,
revision: urlSearchParams.get('revision'),
coverPage: document.getElementById("cover-page-checkbox").checked ? document.getElementById("cover-page-selector").value : null,
css: document.getElementById("css-selector").value,
headerFooter: document.getElementById("header-footer-selector").value,
localization: document.getElementById("localization-selector").value,
webhooks: document.getElementById("webhooks-checkbox").checked ? document.getElementById("webhooks-selector").value : null,
headersColor: document.getElementById("headers-color").value,
paperSize: document.getElementById("paper-size-selector").value,
orientation: document.getElementById("orientation-selector").value,
fitToPage: document.getElementById('fit-to-page').checked,
enableCommentsRendering: document.getElementById('enable-comments-rendering').checked,
watermark: document.getElementById("watermark").checked,
markReferencedWorkitems: document.getElementById("mark-referenced-workitems").checked,
cutEmptyChapters: document.getElementById("cut-empty-chapters").checked,
cutEmptyWIAttributes: document.getElementById('cut-empty-wi-attributes').checked,
cutLocalUrls: document.getElementById("cut-urls").checked,
followHTMLPresentationalHints: document.getElementById("presentational-hints").checked,
numberedListStyles: numberedListStyles,
chapters: selectedChapters,
language: document.getElementById('localization').checked ? document.getElementById("language").value : null,
linkedWorkitemRoles: selectedRoles,
urlQueryParameters: Object.fromEntries([...urlSearchParams]),
});
return new ExportParams.Builder(ExportParams.DocumentType.LIVE_DOC)
.setProjectId(projectId)
.setLocationPath(locationPath)
.setRevision(urlSearchParams.get('revision'))
.setCoverPage(document.getElementById("cover-page-checkbox").checked ? document.getElementById("cover-page-selector").value : null)
.setCss(document.getElementById("css-selector").value)
.setHeaderFooter(document.getElementById("header-footer-selector").value)
.setLocalization(document.getElementById("localization-selector").value)
.setWebhooks(document.getElementById("webhooks-checkbox").checked ? document.getElementById("webhooks-selector").value : null)
.setHeadersColor(document.getElementById("headers-color").value)
.setPaperSize(document.getElementById("paper-size-selector").value)
.setOrientation(document.getElementById("orientation-selector").value)
.setFitToPage(document.getElementById('fit-to-page').checked)
.setEnableCommentsRendering(document.getElementById('enable-comments-rendering').checked)
.setWatermark(document.getElementById("watermark").checked)
.setMarkReferencedWorkitems(document.getElementById("mark-referenced-workitems").checked)
.setCutEmptyChapters(document.getElementById("cut-empty-chapters").checked)
.setCutEmptyWIAttributes(document.getElementById('cut-empty-wi-attributes').checked)
.setCutLocalUrls(document.getElementById("cut-urls").checked)
.setFollowHTMLPresentationalHints(document.getElementById("presentational-hints").checked)
.setNumberedListStyles(numberedListStyles)
.setChapters(selectedChapters)
.setLanguage(document.getElementById('localization').checked ? document.getElementById("language").value : null)
.setLinkedWorkitemRoles(selectedRoles)
.setUrlQueryParameters(Object.fromEntries([...urlSearchParams]))
.build()
.toJSON();
},

getSelectedChapters: function () {
Expand Down
141 changes: 141 additions & 0 deletions src/main/resources/webapp/pdf-exporter/js/modules/ExportContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import ExportParams from "./ExportParams.js";

export default class ExportContext {
projectId = undefined;
locationPath = undefined;
revision = undefined;
documentType = undefined;
urlQueryParameters = undefined;

constructor(documentType = ExportParams.DocumentType.LIVE_DOC, polarionLocationHash = window.location.hash) {
this.documentType = documentType;

const urlPathAndSearchParams = getPathAndQueryParams(polarionLocationHash);
const normalizedPolarionLocationHash = urlPathAndSearchParams.path;
const searchParameters = urlPathAndSearchParams.searchParameters;

const scope = getScope(normalizedPolarionLocationHash);
this.projectId = getProjectId(scope);
this.locationPath = getPath(normalizedPolarionLocationHash, scope);

if (this.locationPath === "testrun") {
this.documentType = ExportParams.DocumentType.TEST_RUN;
}

this.urlQueryParameters = getQueryParams(searchParameters);
this.revision = this.urlQueryParameters?.revision;

console.log(this);

function getPathAndQueryParams(polarionLocationHash) {
const result = {
path: undefined,
searchParameters: undefined
};

if (polarionLocationHash.includes("?")) {
const pathAndQueryParams = decodeURI(polarionLocationHash.substring(2));
const pathAndQueryParamsArray = pathAndQueryParams.split("?");
result.path = pathAndQueryParamsArray[0];
result.searchParameters = pathAndQueryParamsArray[1];
} else {
result.path = decodeURI(polarionLocationHash.substring(2));
}

return result;
}

function getScope(locationHash) {
const projectPattern = /project\/([^/]+)\//;
const projectMatch = projectPattern.exec(locationHash);
return projectMatch ? `project/${projectMatch[1]}/` : "";
}

function getProjectId(scope) {
const foundValues = /project\/(.*)\//.exec(scope);
return foundValues !== null ? foundValues[1] : null;
}

function getPath(locationHash, scope) {
if (scope) {
const pathPattern = /project\/[^/]+\/(wiki\/([^?#]+)|testrun)/;
const pathMatch = pathPattern.exec(locationHash);
return pathMatch ? addDefaultSpaceIfRequired(pathMatch[2] || "testrun") : "";
} else {
const globalPathPattern = /wiki\/([^/?#]+)/;
const pathMatch = globalPathPattern.exec(locationHash);
return pathMatch ? addDefaultSpaceIfRequired(pathMatch[1]) : "";
}
}

function addDefaultSpaceIfRequired(extractedPath) {
if (!extractedPath) {
return "";
}
// if contains a '/' or is exactly 'testrun', return it as it is
if (extractedPath.includes("/") || extractedPath === "testrun") {
return extractedPath;
}
// otherwise, prepend '_default/' to the path
return `_default/${extractedPath}`;
}

function getQueryParams(searchParams) {
if (!searchParameters) {
return undefined;
}

const urlSearchParams = new URLSearchParams(searchParams);
return Object.fromEntries([...urlSearchParams]);
}

}

getProjectId() {
return this.projectId;
}

getLocationPath() {
return this.locationPath;
}

getRevision() {
return this.revision;
}

getDocumentType() {
return this.documentType;
}

getUrlQueryParameters() {
return this.urlQueryParameters;
}

getScope() {
return this.projectId ? `project/${this.projectId}/` : "";
}

getSpaceId() {
const pathParts = this.locationPath.split("/");
return pathParts && pathParts.length > 0 && pathParts[0];
}

getDocumentName() {
const pathParts = this.locationPath.split("/");
return pathParts && pathParts.length > 1 && pathParts[1];
}

toExportParams() {
return new ExportParams.Builder(this.documentType)
.setProjectId(this.projectId)
.setLocationPath(this.locationPath)
.setRevision(this.revision)
.setUrlQueryParameters(this.urlQueryParameters)
.build();
}
}

// expose ExportContext to the global scope
if (typeof window !== 'undefined') {
window.ExportContext = ExportContext;
}
Loading

0 comments on commit a84ec78

Please sign in to comment.