UNPKG

jsf.js_next_gen

Version:

A next generation typescript reimplementation of jsf.js

657 lines (656 loc) 37.8 kB
"use strict"; /*! Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to you under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const mocha_1 = require("mocha"); const StandardInits_1 = require("../frameworkBase/_ext/shared/StandardInits"); const sinon = __importStar(require("sinon")); const XmlResponses_1 = require("../frameworkBase/_ext/shared/XmlResponses"); const chai_1 = require("chai"); const mona_dish_1 = require("mona-dish"); var protocolPage = StandardInits_1.StandardInits.protocolPage; /** * response test * the idea is simply to pass in a dom * the context and a response xml and then check what happens * we do not need to go through the entire ajax cycle for that. */ (0, mocha_1.describe)('Tests of the various aspects of the response protocol functionality', function () { let oldFlatMap = null; beforeEach(function () { return __awaiter(this, void 0, void 0, function* () { let waitForResult = protocolPage(); return waitForResult.then((close) => { this.xhr = sinon.useFakeXMLHttpRequest(); this.requests = []; this.respond = (response) => { let xhrReq = this.requests.shift(); xhrReq.responsetype = "text/xml"; xhrReq.respond(200, { 'Content-Type': 'text/xml' }, response); return xhrReq; }; this.xhr.onCreate = (xhr) => { this.requests.push(xhr); }; global.XMLHttpRequest = this.xhr; window.XMLHttpRequest = this.xhr; oldFlatMap = Array.prototype["flatMap"]; window["Es2019Array"] = mona_dish_1._Es2019Array; delete Array.prototype["flatMap"]; this.closeIt = () => { global.XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore(); Implementation.reset(); close(); }; }); }); }); afterEach(function () { this.closeIt(); if (oldFlatMap) { Array.prototype["flatMap"] = oldFlatMap; oldFlatMap = null; } }); it("must have a simple field updated as well as the viewstate", function (done) { //DQ.byId("cmd_update_insert").click(); mona_dish_1.DQ.byId("cmd_update_insert").click(); this.respond(XmlResponses_1.XmlResponses.UPDATE_INSERT_1); (0, chai_1.expect)(mona_dish_1.DQ.byId("changesArea") .html() .orElse("fail") .value.indexOf("update succeeded 1") != -1) .to.be.true; let pos1 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("insert before succeeded should display before test1"); let pos3 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("insert after succeeded should display after test1"); let pos2 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("update succeeded 1"); (0, chai_1.expect)(pos1 != -1).to.be.true; (0, chai_1.expect)(pos1 < pos2 && pos2 < pos3).to.be.true; let pos4 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("embedded script at update succeed"); (0, chai_1.expect)(pos4 != -1).to.be.true; done(); }); it("must have a simple field updated with the second before update rendering path", function (done) { //DQ.byId("cmd_update_insert").click(); mona_dish_1.DQ.byId("cmd_update_insert").click(); this.respond(XmlResponses_1.XmlResponses.UPDATE_INSERT_2); (0, chai_1.expect)(mona_dish_1.DQ.byId("changesArea") .html() .orElse("fail") .value.indexOf("update succeeded 2") != -1) .to.be.true; let pos1 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("insert before succeeded should display before test1"); let pos3 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("insert after succeeded should display after test1"); let pos2 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("update succeeded 2"); (0, chai_1.expect)(pos1 != -1).to.be.true; (0, chai_1.expect)(pos1 < pos2 && pos2 < pos3).to.be.true; let pos4 = mona_dish_1.DQ.byId(document.body).html() .value.indexOf("embedded script at update succeed"); (0, chai_1.expect)(pos4 != -1).to.be.true; done(); }); it("must have a full body update", function () { mona_dish_1.DQ.byId("cmd_replace").click(); this.respond(XmlResponses_1.XmlResponses.BODY_REPLACEMENT); //basic replacement let newBody = mona_dish_1.DQ.byId(document.body); let newContent = newBody.html().value; //standard replacement successful (0, chai_1.expect)(newContent.indexOf("<h3>Body replacement test successful</h3>") != -1, "elements must be updated").to.be.true; //script eval (0, chai_1.expect)(newContent.indexOf(">hello from embedded script in replacement body<") != -1, "embedded scripts must be executed").to.be.true; //body attributes (0, chai_1.expect)(newBody.hasClass("tundra"), "attributes must be updated").to.be.true; (0, chai_1.expect)(newBody.id.value == "the_id", "id must be updated").to.be.true; }); it("must have a proper working head replace", function () { mona_dish_1.DQ.byId("cmd_replace").click(); this.respond(XmlResponses_1.XmlResponses.HEAD_REPLACEMENT); //basic replacement let newBody = mona_dish_1.DQ.byId(document.body); let newContent = newBody.html().value; //standard replacement successful //script eval //modern browsers block head replacement but you still can eval (0, chai_1.expect)(newContent.indexOf(">hello from embedded script in replacement head") != -1, "embedded scripts must be executed").to.be.true; }); it("must have a proper workiung root replace", function () { mona_dish_1.DQ.byId("cmd_replace").click(); this.respond(XmlResponses_1.XmlResponses.VIEW_ROOT_REPLACEMENT); //basic replacement let newHead = mona_dish_1.DQ.byId(document.head); let newBody = mona_dish_1.DQ.byId(document.body); let newContent = newBody.html().value; (0, chai_1.expect)(newHead.isPresent(), " head must exist ").to.be.true; //standard replacement successful (0, chai_1.expect)(newContent.indexOf("<h3>Body replacement test successful</h3>") != -1, "elements must be updated").to.be.true; //script eval (0, chai_1.expect)(newContent.indexOf(">hello from embedded script in replacement body<") != -1, "embedded scripts must be executed").to.be.true; //body attributes (0, chai_1.expect)(newBody.hasClass("tundra"), "attributes must be updated").to.be.true; (0, chai_1.expect)(newBody.id.value == "the_id", "id must be updated").to.be.true; //standard replacement successful //script eval //modern browsers block head replacement but you still can eval (0, chai_1.expect)(newContent.indexOf(">hello from embedded script in replacement head") != -1, "embedded scripts must be executed").to.be.true; }); it("must have a viewState update to be performed", function () { mona_dish_1.DQ.byId("cmd_viewstate").click(); this.respond(XmlResponses_1.XmlResponses.VIEWSTATE_1); let viewStateElem = mona_dish_1.DQ.byId('jakarta.faces.ViewState'); (0, chai_1.expect)(viewStateElem.inputValue.value == "hello world").to.be.true; }); it("must have processed a proper delete", function () { mona_dish_1.DQ.byId("cmd_delete").click(); this.respond(XmlResponses_1.XmlResponses.DELETE_1); (0, chai_1.expect)(mona_dish_1.DQ.byId("deletable").isAbsent()).to.be.true; }); it("must have processed a proper eval of a script given in the eval tag", function () { mona_dish_1.DQ.byId("cmd_eval").click(); this.respond(XmlResponses_1.XmlResponses.EVAL_1); let resultHTML = mona_dish_1.DQ.byId(document.body).html().value; (0, chai_1.expect)(resultHTML.indexOf('eval test succeeded') != -1).to.be.true; }); it("must have updated the viewstates properly", function (done) { mona_dish_1.DQ.byId("cmd_eval").click(); /*js full submit form, coming from the integration tests*/ window.document.body.innerHTML = `<form id="j_id__v_0" name="j_id__v_0" method="post" action="/IntegrationJSTest/integrationtestsjasmine/test7-eventtest.jsf" ><span id="updatePanel">hello world</span><a href="#" onclick="return faces.util.chain(this, event,'return false;', 'return myfaces.ab(\'j_id_1l\',\'updateTrigger\');');" id="updateTrigger" name="updateTrigger" class="updateTrigger">[Press me for Update]</a><input type="hidden" name="j_id_1l_SUBMIT" value="1"> </form>`; faces.ajax.request(window.document.getElementById("updateTrigger"), null, { render: "updatePanel", execute: "updatePanel updateTrigger" }); // language=XML this.respond(`<?xml version="1.0" encoding="UTF-8"?> <partial-response id="j_id__v_0"> <changes> <update id="updatePanel"><![CDATA[<span id="updatePanel">hello world</span>]]></update> <update id="j_id__v_0:jakarta.faces.ViewState:1"><![CDATA[RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD]]></update> </changes> </partial-response>`); setTimeout(() => { (0, chai_1.expect)((0, mona_dish_1.DQ$)("[name*='jakarta.faces.ViewState']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("[name*='jakarta.faces.ViewState']").val == "RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD").to.be.true; done(); }, 100); }); it("must have updated the viewstates properly with lenient update block", function () { mona_dish_1.DQ.byId("cmd_eval").click(); /*js full submit form, coming from the integration tests*/ window.document.body.innerHTML = `<form id="j_id__v_0" name="j_id__v_0" method="post" action="/IntegrationJSTest/integrationtestsjasmine/test7-eventtest.jsf" ><span id="updatePanel">hello world</span><a href="#" onclick="return faces.util.chain(this, event,'return false;', 'return myfaces.ab(\'j_id_1l\',\'updateTrigger\');');" id="updateTrigger" name="updateTrigger" class="updateTrigger">[Press me for Update]</a><input type="hidden" name="j_id_1l_SUBMIT" value="1"> </form>`; faces.ajax.request(window.document.getElementById("updateTrigger"), null, { render: "updatePanel", execute: "updatePanel updateTrigger" }); // language=XML this.respond(`<?xml version="1.0" encoding="UTF-8"?> <partial-response id="j_id__v_0"> <changes> <update id="updatePanel"><![CDATA[<span id="updatePanel">hello world</span>]]></update> <update id="j_id__v_0:jakarta.faces.ViewState:1"><![CDATA[RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD]]><!-- Some random junk which is sent by the server --></update> </changes> </partial-response>`); (0, chai_1.expect)((0, mona_dish_1.DQ$)("[name*='jakarta.faces.ViewState']").isAbsent()).to.be.false; // expect((<HTMLInputElement>document.getElementsByName("jakarta.faces.ViewState")[0]).value == "RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD").to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("[name*='jakarta.faces.ViewState']").inputValue.value == "RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD").to.be.true; }); /** * The body innerHTML is based on a Tobago page. View state and client window id is rendered within a * jsf-state-container. * Beside the tobago-out tag, the view state and the client window id must be updated properly. */ it("must have updated the client window tag properly", function () { window.document.body.innerHTML = `<tobago-page locale='en' class='container-fluid' id='page'> <form action='/IntegrationJSTest/integrationtestsjasmine/tobago-jfwid-test.jsf' id='page::form' method='post' accept-charset='UTF-8' data-tobago-context-path=''> <input type='hidden' name='jakarta.faces.source' id='jakarta.faces.source' disabled='disabled'> <tobago-focus id='page::lastFocusId'> <input type='hidden' name='page::lastFocusId' id='page::lastFocusId::field'> </tobago-focus> <input type='hidden' name='org.apache.myfaces.tobago.webapp.Secret' id='org.apache.myfaces.tobago.webapp.Secret' value='SLrPlxqLEaR/oYFLSu4wgg=='> <tobago-in id='page:input' class='tobago-margin-bottom'> <input type='text' name='page:input' id='page:input::field' class='tobago-in form-control' value='Alice'> <tobago-behavior event='change' client-id='page:input' field-id='page:input::field' execute='page:input' render='page:output'></tobago-behavior> </tobago-in> <div id='page:output' class='tobago-margin-bottom'> <tobago-out class='form-control-plaintext'></tobago-out> </div> <div class='tobago-page-menuStore'></div> <span id='page::jsf-state-container'> <input type='hidden' name='jakarta.faces.ViewState' id='j_id__v_0:jakarta.faces.ViewState:1' value='RkExQ0Q1NTYzOTNCNzg0RjAwMDAwMDE4' autocomplete='off'> <input type='hidden' name='jakarta.faces.RenderKitId' value='tobago'> <input type='hidden' id='j_id__v_0:jakarta.faces.ClientWindow:1' name='jakarta.faces.ClientWindow' value='5m10kooxi'> </span> </form> </tobago-page>`; (0, chai_1.expect)(mona_dish_1.DQ.querySelectorAll("#page\\:output tobago-out").textContent() === "").to.be.true; (0, chai_1.expect)(mona_dish_1.DQ.byId("j_id__v_0:jakarta.faces.ViewState:1").isAbsent()).to.be.false; (0, chai_1.expect)(mona_dish_1.DQ.byId("j_id__v_0:jakarta.faces.ClientWindow:1").isAbsent()).to.be.false; faces.ajax.request(window.document.getElementById("page:input"), "change", { "jakarta.faces.behavior.event": "change", execute: "page:input", render: "page:output" }); this.respond(`<?xml version="1.0" encoding="UTF-8"?> <partial-response id='j_id__v_0'> <changes> <update id='page:output'><![CDATA[ <div id='page:output' class='tobago-margin-bottom'> <tobago-out class='form-control-plaintext'>Alice</tobago-out> </div>]]> </update> <update id='j_id__v_0:jakarta.faces.ViewState:1'><![CDATA[MDQwQzkxNkU0MTg0RTQxRjAwMDAwMDE3]]> </update> <update id='j_id__v_0:jakarta.faces.ClientWindow:1'><![CDATA[5m10kooxg]]> </update> </changes> </partial-response>`); (0, chai_1.expect)(mona_dish_1.DQ.querySelectorAll("#page\\:output tobago-out").textContent() === "Alice").to.be.true; (0, chai_1.expect)(mona_dish_1.DQ.byId("j_id__v_0:jakarta.faces.ViewState:1").isAbsent()).to.be.false; (0, chai_1.expect)(mona_dish_1.DQ.byId("j_id__v_0:jakarta.faces.ClientWindow:1").isAbsent()).to.be.false; }); it("must handle simple resource responses properly", function (done) { // we need to fake the response as well to see whether the server has loaded the addedViewHead code and has interpreted it //(window as any)["test"] = "booga"; mona_dish_1.DQ.byId("cmd_simple_resource").click(); this.respond(XmlResponses_1.XmlResponses.SIMPLE_RESOURCE_RESPONSE); (0, chai_1.expect)(document.head.innerHTML.indexOf("../../../xhrCore/fixtures/addedViewHead1.js") != -1).to.be.true; mona_dish_1.DQ.byId(document.body).waitUntilDom(() => mona_dish_1.DQ.byId('resource_area_1').innerHTML === "true") .then(() => done()) .catch(done); }); it("only single resources are allowed", function (done) { // we need to fake the response as well to see whether the server has loaded the addedViewHead code and has interpreted it //(window as any)["test"] = "booga"; for (let cnt = 0; cnt < 10; cnt++) { mona_dish_1.DQ.byId("cmd_simple_resource").click(); this.respond(XmlResponses_1.XmlResponses.MULTIPLE_RESOURCE_RESPONSE); } (0, chai_1.expect)(document.head.innerHTML.indexOf("../../../xhrCore/fixtures/addedViewHead2.js") != -1).to.be.true; let addedScriptsCnt = mona_dish_1.DomQuery.byId(document.head).querySelectorAll("script[src='../../../xhrCore/fixtures/addedViewHead2.js']").length; (0, chai_1.expect)(addedScriptsCnt).to.eq(1); addedScriptsCnt = mona_dish_1.DomQuery.byId(document.head).querySelectorAll("style[rel='../../../xhrCore/fixtures/addedViewHead2.css']").length; (0, chai_1.expect)(addedScriptsCnt).to.eq(1); done(); }); //TODO implement secondary response mockup it("must handle complex resource responses properly", function (done) { mona_dish_1.DQ.byId("cmd_complex_resource").click(); this.respond(XmlResponses_1.XmlResponses.MULTIPLE_RESOURCE_RESPONSE); let headHTML = document.head.innerHTML; (0, chai_1.expect)(headHTML.indexOf("../../../xhrCore/fixtures/addedViewHead2.js")).not.eq(-1); (0, chai_1.expect)(headHTML.indexOf("rel=\"../../../xhrCore/fixtures/addedViewHead2.css\"")).not.eq(-1); mona_dish_1.DQ.byId(document.body).waitUntilDom(() => mona_dish_1.DQ.byId('resource_area_2').innerHTML === "true2") .then(() => done()) .catch(done); }); it("embedded scripts must be evaled", function (done) { mona_dish_1.DQ.byId("cmd_complex_resource2").click(); this.respond(XmlResponses_1.XmlResponses.EMBEDDED_SCRIPTS_RESOURCE_RESPONSE); // this.respond("debugger; document.getElementById('resource_area_1').innerHTML = 'true3'", {'Content-Type': 'text/javascript'}); let headHTML = document.head.innerHTML; (0, chai_1.expect)(headHTML.indexOf("../../../xhrCore/fixtures/addedViewHead3.js")).not.eq(-1); (0, chai_1.expect)(headHTML.indexOf("href=\"../../../xhrCore/fixtures/addedViewHead2.css\"")).not.eq(-1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("head link[rel='stylesheet'][href='../../../xhrCore/fixtures/addedViewHead2.css']").length).to.eq(1); setTimeout(() => { let evalAreaHtml = mona_dish_1.DQ.byId('resource_area_1').innerHTML; //last one must be the last item, order must be preserved (0, chai_1.expect)(evalAreaHtml).to.eq("booga"); done(); }, 800); }); it("head replacement must work (https://issues.apache.org/jira/browse/MYFACES-4498 and TCK Issue 4345IT)", function (done) { mona_dish_1.DQ.byId("cmd_complex_resource2").click(); this.respond(XmlResponses_1.XmlResponses.HEAD_REPLACE); let headHTML = document.head.innerHTML; //failing now, no elements in the html head after respond!!! (0, chai_1.expect)(headHTML.indexOf("href=\"../../../xhrCore/fixtures/addedViewHead2.css\"")).not.eq(-1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("head link[rel='stylesheet'][href='../../../xhrCore/fixtures/addedViewHead2.css']").length).to.eq(1); (0, chai_1.expect)(headHTML.indexOf("../../../xhrCore/fixtures/addedViewHead3.js")).not.eq(-1); setTimeout(() => { let evalAreaHtml = mona_dish_1.DQ.byId('resource_area_1').innerHTML; //last one must be the last item, order must be preserved (0, chai_1.expect)(evalAreaHtml).to.eq("booga"); done(); }, 800); }); it("complex head replacement must work", function (done) { mona_dish_1.DQ.byId("cmd_complex_resource2").click(); this.respond(XmlResponses_1.XmlResponses.HEAD_REPLACE2); let headHTML = document.head.innerHTML; //failing now, no elements in the html head after respond!!! (0, chai_1.expect)(headHTML.indexOf("href=\"../../../xhrCore/fixtures/addedViewHead2.css\"")).not.eq(-1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("head link[rel='stylesheet'][href='../../../xhrCore/fixtures/addedViewHead2.css']").length).to.eq(1); let metas = (0, mona_dish_1.DQ$)("head meta"); (0, chai_1.expect)(metas.length).to.eq(5); (0, chai_1.expect)(metas.get(0).attr("charSet").value == "UTF-8"); (0, chai_1.expect)(metas.get(4).attr("author").value == "Whoever"); (0, chai_1.expect)(headHTML.indexOf("../../../xhrCore/fixtures/addedViewHead3.js")).not.eq(-1); setTimeout(() => { let evalAreaHtml = mona_dish_1.DQ.byId('resource_area_1').innerHTML; //last one must be the last item, order must be preserved (0, chai_1.expect)(evalAreaHtml).to.eq("booga"); done(); }, 800); }); const INNER_HTML_MULIT_VIEW = ` <div id="viewroot_1"> <form id="viewroot_1:form1"> <button type="submit" id="viewroot_1:submit_1"></button> <input type="hidden" id="viewroot_1:form1:jakarta.faces.ViewState:1" name="jakarta.faces.ViewState" value="booga"></input> </form> <form id="viewroot_1:form2"> <button type="submit" id="viewroot_1:submit_2"></button> </form> </div> <div id="viewroot_2"> <form id="viewroot_2:form1"> <button type="submit" id="viewroot_1:submit_2"></button> </form> </div> `; it("must handle multiple view roots", function (done) { const RESPONSE_1 = `<?xml version="1.0" encoding="UTF-8"?> <partial-response id='viewroot_1'> <changes> <update id='viewroot_1:jakarta.faces.ViewState:1'><![CDATA[updatedVST]]></update> </changes> </partial-response>`; window.document.body.innerHTML = INNER_HTML_MULIT_VIEW; faces.ajax.request(window.document.getElementById("viewroot_1:submit_1"), null, { "javax.faces.behavior.event": "change", execute: "submit_1", render: "form1" }); this.respond(RESPONSE_1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form2 [name='jakarta.faces.ViewState']").isAbsent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name='jakarta.faces.ViewState']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name='jakarta.faces.ViewState']").val).to.be.eq("updatedVST"); done(); }); it("must handle multiple view roots multi forms", function (done) { const RESPONSE_1 = `<?xml version="1.0" encoding="UTF-8"?> <partial-response id='viewroot_1'> <changes> <update id='viewroot_1:jakarta.faces.ViewState:1'><![CDATA[updatedVST]]></update> </changes> </partial-response>`; window.document.body.innerHTML = INNER_HTML_MULIT_VIEW; faces.ajax.request(window.document.getElementById("viewroot_1:submit_1"), null, { "javax.faces.behavior.event": "change", execute: "submit_1", render: "viewroot_1:form1 submit_2" }); this.respond(RESPONSE_1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form2 [name*='jakarta.faces.ViewState']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name*='jakarta.faces.ViewState']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_2\\:form1\\:form1 [name*='jakarta.faces.ViewState']").isAbsent()).to.be.true; (0, chai_1.expect)(faces.getViewState((0, mona_dish_1.DQ$)("#viewroot_1\\:form2").getAsElem(0).value).indexOf("jakarta.faces.ViewState=updatedVST") != -1).to.be.true; (0, chai_1.expect)(faces.getViewState("viewroot_1:form1").indexOf("jakarta.faces.ViewState=updatedVST") != -1).to.be.true; done(); }); it("must handle multiple view roots with ClientWindow ids", function (done) { const RESPONSE_1 = `<?xml version="1.0" encoding="UTF-8"?> <partial-response id='viewroot_1'> <changes> <update id='viewroot_1:jakarta.faces.ClientWindow:1'><![CDATA[updatedViewId]]></update> </changes> </partial-response>`; window.document.body.innerHTML = INNER_HTML_MULIT_VIEW; faces.ajax.request(window.document.getElementById("viewroot_1:submit_1"), null, { "javax.faces.behavior.event": "change", execute: "submit_1", render: "viewroot_1:form1" }); this.respond(RESPONSE_1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form2 [name*='jakarta.faces.ClientWindow']").isAbsent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name*='jakarta.faces.ClientWindow']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name*='jakarta.faces.ClientWindow']").val).to.be.eq("updatedViewId"); done(); }); it("must handle multiple view roots multi forms with ClientWindow ids", function (done) { const RESPONSE_1 = `<?xml version="1.0" encoding="UTF-8"?> <partial-response id='viewroot_1'> <changes> <update id='viewroot_1:jakarta.faces.ClientWindow:1'><![CDATA[updatedViewId]]></update> </changes> </partial-response>`; window.document.body.innerHTML = INNER_HTML_MULIT_VIEW; faces.ajax.request(window.document.getElementById("viewroot_1:submit_1"), null, { "javax.faces.behavior.event": "change", execute: "submit_1", render: "viewroot_1:form1 :submit_2" }); this.respond(RESPONSE_1); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form2 [name*='jakarta.faces.ClientWindow']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name*='jakarta.faces.ClientWindow']").isPresent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_2\\:form1\\:form1 [name*='jakarta.faces.ClientWindow']").isAbsent()).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form2 [name*='jakarta.faces.ClientWindow']").val).to.be.eq("updatedViewId"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#viewroot_1\\:form1 [name*='jakarta.faces.ClientWindow']").val).to.be.eq("updatedViewId"); done(); }); const TCK_790_MARKUP = ` <div id="panel1"> <form id="form1" name="form1" method="post" action="booga" ><input id="form1:button" name="form1:button" type="submit" value="submit form1 via ajax"> <input type="hidden" name="jakarta.faces.ViewState" id="viewroot_1:jakarta.faces.ViewState:1" value="beforeUpdate"> </form> </div> <div id="panel2"> <form id="form2" name="form2" method="post" action="booga2" ><a href="#" id="form2:link" name="form2:link"></a> </form> </div> <div id="panel3"> <form id="form3" name="form3" method="post" action="booga3" ><a href="#" id="form3:link" name="form3:link"></a> </form> </div> `; const TCK_790_NAV_MARKUP = ` <form id="form1x" name="form1" method="post" action="booga" ><input id="form1x:button" name="form1x:button" type="submit" value="submit form1 via ajax"> <input type="hidden" name="jakarta.faces.ViewState" id="viewroot_1:jakarta.faces.ViewState:1" value="beforeUpdate"> </form> `; /** * Similar to TCK 790 */ it("must handle a more complex replace with several forms and one issuing form and a viewstate and a viewroot id in response but viewroot is not present in page", function (done) { document.body.innerHTML = TCK_790_MARKUP; const RESPONSE_1 = `<partial-response id="viewroot_1"> <changes> <update id="panel2"><![CDATA[ <div id="panel2"> after update <form id="form2" name="form2" method="post" action="booga2" ><a href="#" id="form2:link" name="form2:link"></a> <input type="hidden" name="form2_SUBMIT" value="1"/></form> </div> ]]> </update> <update id="panel3"><![CDATA[ <div id="panel3"> after update <form id="form3" name="form3" method="post" action="booga3" ><a href="#" id="form3:link" name="form3:link"></a> </form> </div> ]]> </update> <update id="viewroot_1:jakarta.faces.ViewState:1"><![CDATA[booga_after_update]]></update> </changes> </partial-response>`; faces.ajax.request(window.document.getElementById("form1:button"), null, { "javax.faces.behavior.event": "click", execute: "form1", render: "form2 form3" }); this.respond(RESPONSE_1); // all forms in execute and render must receive the latest viewstate (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form1 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form2 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form2 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); done(); }); it("must handle a complex navigation response (TCK Spec790)", function (done) { /*we start from a simple form which triggers a an internal navigation*/ document.body.innerHTML = TCK_790_NAV_MARKUP; faces.ajax.request(window.document.getElementById("form1x:button"), null, { "javax.faces.behavior.event": "click", execute: "@form", render: ":form1x:button" }); //TODO xhr stubbing, to check if the viewId is prepended in render! global["state_1"] = true; this.respond(`<?xml version="1.0" encoding="UTF-8"?> <partial-response id="viewroot_1"> <changes> <update id="jakarta.faces.ViewRoot"><![CDATA[<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Spec 790</title> <script src="/jakarta.faces.resource/faces.js.xhtml?ln=jakarta.faces;stage=Development"></script> </head> <body> <div id="panel1"> <form id="form1" name="form1" method="post" action="booga" ><input id="form1:button" name="form1:button" type="submit" value="submit form1 via ajax"> </form> </div> <div id="panel2"> after update <form id="form2" name="form2" method="post" action="booga2" ><a href="#" id="form2:link" name="form2:link"></a> <input type="hidden" name="form2_SUBMIT" value="1"/></form> </div> <div id="panel3"> after update <form id="form3" name="form3" method="post" action="booga3" ><a href="#" id="form3:link" name="form3:link"></a> </form> </div> </body> </html> ]]> </update> <update id="viewroot_1:jakarta.faces.ViewState:1"><![CDATA[booga_after_update]]></update> </changes> </partial-response> `); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form1 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form2 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form3 [name*='jakarta.faces.ViewState']").val).to.eq("booga_after_update"); (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form1 [name*='jakarta.faces.ViewState']").id.value.indexOf("viewroot_1:jakarta.faces.ViewState:1") === 0).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form2 [name*='jakarta.faces.ViewState']").id.value.indexOf("viewroot_1:jakarta.faces.ViewState:2") === 0).to.be.true; (0, chai_1.expect)((0, mona_dish_1.DQ$)("#form3 [name*='jakarta.faces.ViewState']").id.value.indexOf("viewroot_1:jakarta.faces.ViewState:3") === 0).to.be.true; done(); }); it('must handle a ViewExpired Error correctly, and only once in a listener', function (done) { document.body.innerHTML = TCK_790_NAV_MARKUP; const oldErr = console.error; console.error = () => { }; try { let errorCalled = 0; faces.ajax.addOnError((error) => { (0, chai_1.expect)(error.errorName).to.eq("jakarta.faces.application.ViewExpiredException"); (0, chai_1.expect)(error.errorMessage).to.eq("serverError: View \"/testhmtl.xhtml\" could not be restored."); (0, chai_1.expect)(error.source.id).to.eq("form1x:button"); errorCalled++; }); faces.ajax.request(window.document.getElementById("form1x:button"), null, { "javax.faces.behavior.event": "click", execute: "@form", render: ":form1x:button" }); this.respond(`<?xml version="1.0" encoding="UTF-8"?> <partial-response><error> <error-name>jakarta.faces.application.ViewExpiredException</error-name> <error-message><![CDATA[View "/testhmtl.xhtml" could not be restored.]]></error-message> </error> </partial-response>`); (0, chai_1.expect)(errorCalled).to.eq(1); } finally { console.error = oldErr; } done(); }); }); //# sourceMappingURL=ResponseTest.spec.js.map