From: <rb...@us...> - 2014-01-27 17:15:05
|
Revision: 9074 http://sourceforge.net/p/htmlunit/code/9074 Author: rbri Date: 2014-01-27 17:15:00 +0000 (Mon, 27 Jan 2014) Log Message: ----------- next bulk IE11 update from frank; again more tests migrated to webdriver Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/EventListenersContainer.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLDocument.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HTMLParser4Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/IEConditionalCommentExpressionEvaluatorTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptableTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/Window2Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/WindowTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSImportRuleTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParserTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLDocumentTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLFormElementTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLFrameElement2Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLDocument3Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLDocumentTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest2Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest3Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequestTest.java Added Paths: ----------- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable2Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/Window3Test.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/changes/changes.xml 2014-01-27 17:15:00 UTC (rev 9074) @@ -9,6 +9,21 @@ <body> <release version="2.14" date="???" description="FF24, Bugfixes, initial work on IE11"> <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: CORS handling is different in IE11 for the 'about:' protocol. + </action> + <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: Window many property fixes for IE11 and Chrome. + </action> + <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: CSSFontFace rule cssText property fixed for IE11. + </action> + <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: style zIndex is of type integer in IE11. + </action> + <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: DOMParser.parseFromString() type checking fixed. + </action> + <action type="fix" dev="rbri" due-to="Frank Danek"> JavaScript: Function HTMLelement.insertAdjacentText added (IE, Chrome). </action> <action type="update" dev="asashour"> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -71,6 +71,10 @@ @BrowserFeature({ @WebBrowser(FF), @WebBrowser(CHROME) }) CSS_DISPLAY_DEFAULT, + /** <code>CSSFontFaceRule.cssText</code> uses \r\n to break lines. */ + @BrowserFeature(@WebBrowser(value = IE, minVersion = 11)) + CSS_FONTFACERULE_CSSTEXT_CRLF, + /** Default is 'normal'. */ @BrowserFeature({ @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) CSS_FONT_STRECH_DEFAULT_NORMAL, @@ -122,6 +126,10 @@ @BrowserFeature({ @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) CSS_TEXT_SHADOW_DEFAULT_NONE, + /** zIndex is of type Integer. Other values are ignored (''). */ + @BrowserFeature(@WebBrowser(value = IE, minVersion = 11)) + CSS_ZINDEX_TYPE_INTEGER, + /** IE uses the type Number for the zIndex Values (instead of String). */ @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) CSS_ZINDEX_TYPE_NUMBER, @@ -226,6 +234,10 @@ @BrowserFeature({ @WebBrowser(FF), @WebBrowser(CHROME), @WebBrowser(value = IE, minVersion = 11) }) EVENT_ONLOAD_IFRAME_CREATED_BY_JAVASCRIPT, + /** Setting the 'onload' event handler to <code>undefined</code> throws an error. */ + @BrowserFeature(@WebBrowser(value = IE, maxVersion = 8)) + EVENT_ONLOAD_UNDEFINED_THROWS_ERROR, + /** Does not trigger "onmousedown" event handler for the select options. */ @BrowserFeature({ @WebBrowser(IE) }) EVENT_ONMOUSEDOWN_FOR_SELECT_OPTION_TRIGGERS_ADDITIONAL_DOWN_FOR_SELECT, @@ -679,7 +691,7 @@ JS_APPEND_CHILD_THROWS_NO_EXCEPTION_FOR_WRONG_NODE, /** Indicates that the class name of "arguments" object is "Object". */ - @BrowserFeature(@WebBrowser(IE)) + @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) JS_ARGUMENTS_IS_OBJECT, /** Indicates that "someFunction.arguments" is a read-only view of the function's argument. */ @@ -968,12 +980,14 @@ @BrowserFeature(@WebBrowser(FF)) JS_EVENT_DISTINGUISH_PRINTABLE_KEY, - /** Javascript event handlers declared as property on a node - * don't receive the event as argument. - */ + /** Javascript event handlers declared as property on a node don't receive the event as argument. */ @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) JS_EVENT_HANDLER_AS_PROPERTY_DONT_RECEIVE_EVENT, + /** If an event handler has the value <code>undefined</code> <code>null</code> is returned instead. */ + @BrowserFeature({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) + JS_EVENT_HANDLER_UNDEFINED_AS_NULL, + /** Javascript event.keyCode returns undefined instead of zero if the keyCode is not set. */ @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) JS_EVENT_KEY_CODE_UNDEFINED, @@ -1198,9 +1212,10 @@ @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) JS_SCRIPT_ALWAYS_REEXECUTE_ON_SET_TEXT, - /** Always execute the script if IE; - * in FF, only execute if the old "src" attribute was undefined - * and there was no inline code. + /** + * Always execute the script if IE; + * in FF, only execute if the old "src" attribute was undefined + * and there was no inline code. */ @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) JS_SCRIPT_ALWAYS_REEXECUTE_ON_SRC_CHANGE, @@ -1472,8 +1487,8 @@ @BrowserFeature({ @WebBrowser(FF), @WebBrowser(CHROME) }) PROTOCOL_DATA, - /** Indicates .querySelectorAll() is not supported in quirks mode. */ - @BrowserFeature(@WebBrowser(value = IE, minVersion = 8, maxVersion = 9)) + /** Indicates <code>.querySelectorAll()</code> and <code>.querySelector()</code> is not supported in quirks mode. */ + @BrowserFeature(@WebBrowser(value = IE, minVersion = 8)) QUERYSELECTORALL_NOT_IN_QUIRKS, /** Document mode is always 5 in quirks mode ignoring the browser version. */ @@ -1498,10 +1513,9 @@ /** * Indicates that a read only JS property can potentially be set. * If supported, {@link net.sourceforge.htmlunit.corejs.javascript.ScriptableObject}.isReadOnlySettable() - * will be checked, - * if not supported, an exception will be thrown. + * will be checked, if not supported, an exception will be thrown. */ - @BrowserFeature(@WebBrowser(FF)) + @BrowserFeature({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) SET_READONLY_PROPERTIES, /** Indicates that string.contains() is supported. */ @@ -1599,9 +1613,9 @@ @BrowserFeature(@WebBrowser(value = IE, minVersion = 11)) XHR_IGNORE_PORT_FOR_SAME_ORIGIN, - /** Indicates if a request to a about URL is allowed. */ - @BrowserFeature(@WebBrowser(value = IE, maxVersion = 9)) - XHR_IGNORE_SAME_ORIGIN_TO_ABOUT, + /** A cross origin request to about:blank is not allowed. */ + @BrowserFeature(@WebBrowser(value = IE, minVersion = 11)) + XHR_NO_CROSS_ORIGIN_TO_ABOUT, /** Indicates that the onreadystatechange handler is triggered for sync requests for COMPLETED (4). */ @BrowserFeature({ @WebBrowser(value = FF, minVersion = 10), @WebBrowser(CHROME), Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/EventListenersContainer.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/EventListenersContainer.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/EventListenersContainer.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -15,6 +15,7 @@ package com.gargoylesoftware.htmlunit.javascript.host; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.GENERATED_40; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_EVENT_HANDLER_UNDEFINED_AS_NULL; import java.io.Serializable; import java.util.ArrayList; @@ -24,6 +25,7 @@ import java.util.Map; import net.sourceforge.htmlunit.corejs.javascript.Function; +import net.sourceforge.htmlunit.corejs.javascript.Undefined; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -133,8 +135,15 @@ * @param value the new property */ public void setEventHandlerProp(final String eventName, final Object value) { + Object handler = value; + if (jsNode_.getWindow().getWebWindow().getWebClient().getBrowserVersion() + .hasFeature(JS_EVENT_HANDLER_UNDEFINED_AS_NULL) + && Undefined.instance == value) { + handler = null; + } + final Handlers handlers = getHandlersOrCreateIt(eventName); - handlers.handler_ = value; + handlers.handler_ = handler; } /** @@ -147,7 +156,6 @@ if (handlers == null) { return null; } - // TODO: handle differences between IE and FF: null vs undefined return handlers.handler_; } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -14,6 +14,7 @@ */ package com.gargoylesoftware.htmlunit.javascript.host; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONLOAD_UNDEFINED_THROWS_ERROR; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.GENERATED_133; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_EVENT_HANDLER_AS_PROPERTY_DONT_RECEIVE_EVENT; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_CHANGE_OPENER_NOT_ALLOWED; @@ -1048,6 +1049,10 @@ */ @JsxSetter public void setOnload(final Object newOnload) { + if (getBrowserVersion().hasFeature(EVENT_ONLOAD_UNDEFINED_THROWS_ERROR) + && Context.getUndefinedValue().equals(newOnload)) { + throw Context.reportRuntimeError("Invalid onload value: undefined."); + } getEventListenersContainer().setEventHandlerProp("load", newOnload); } @@ -1169,7 +1174,7 @@ * @param listener the event listener * @see <a href="http://msdn.microsoft.com/en-us/library/ms536411.aspx">MSDN documentation</a> */ - @JsxFunction(@WebBrowser(IE)) + @JsxFunction(@WebBrowser(value = IE, maxVersion = 9)) public void detachEvent(final String type, final Function listener) { getEventListenersContainer().removeEventListener(StringUtils.substring(type, 2), listener, false); } @@ -1412,11 +1417,9 @@ } /** - * Executes the specified script code as long as the language is JavaScript or JScript. Does - * nothing if the language specified is VBScript. - * Note: MSDN doc says that the function returns null but in fact this is undefined. + * Executes the specified script code as long as the language is JavaScript or JScript. * @param script the script code to execute - * @param language the language of the specified code ("JavaScript", "JScript" or "VBScript") + * @param language the language of the specified code ("JavaScript" or "JScript") * @see <a href="http://msdn.microsoft.com/en-us/library/ms536420.aspx">MSDN documentation</a> */ @JsxFunction(@WebBrowser(value = IE, maxVersion = 9)) @@ -1427,7 +1430,7 @@ ScriptRuntime.evalSpecial(Context.getCurrentContext(), this, this, new Object[] {script}, null, 0); } else if ("vbscript".equalsIgnoreCase(languageStr)) { - LOG.warn("VBScript not supported in Window.execScript()."); + throw Context.reportRuntimeError("VBScript not supported in Window.execScript()."); } else { // Unrecognized language: use the IE error message ("Invalid class string"). @@ -1521,7 +1524,7 @@ * @return a dummy value * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref28.html">Mozilla doc</a> */ - @JsxGetter({ @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) + @JsxGetter({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public int getInnerWidth() { return getWebWindow().getInnerWidth(); } @@ -1531,7 +1534,7 @@ * @return a dummy value * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref79.html">Mozilla doc</a> */ - @JsxGetter(@WebBrowser(FF)) + @JsxGetter({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public int getOuterWidth() { return getWebWindow().getOuterWidth(); } @@ -1541,7 +1544,7 @@ * @return a dummy value * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref27.html">Mozilla doc</a> */ - @JsxGetter({ @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) + @JsxGetter({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public int getInnerHeight() { return getWebWindow().getInnerHeight(); } @@ -1551,7 +1554,7 @@ * @return a dummy value * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_window_ref78.html">Mozilla doc</a> */ - @JsxGetter(@WebBrowser(FF)) + @JsxGetter({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public int getOuterHeight() { return getWebWindow().getOuterHeight(); } @@ -1574,7 +1577,7 @@ * @param type the type of events to capture * @see Document#captureEvents(String) */ - @JsxFunction(@WebBrowser(FF)) + @JsxFunction({ @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public void captureEvents(final String type) { // Empty. } @@ -1920,7 +1923,7 @@ * (currently empty implementation) * @see <a href="https://developer.mozilla.org/en/DOM/window.stop">window.stop</a> */ - @JsxFunction(@WebBrowser(FF)) + @JsxFunction({ @WebBrowser(CHROME), @WebBrowser(FF) }) public void stop() { //empty } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -14,6 +14,7 @@ */ package com.gargoylesoftware.htmlunit.javascript.host.css; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_CRLF; import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.FF; import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.IE; @@ -66,11 +67,18 @@ @JsxGetter({ @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) public String getCssText() { String cssText = super.getCssText(); - cssText = StringUtils.replace(cssText, "{", "{\n "); - cssText = StringUtils.replace(cssText, "}", ";\n}"); - cssText = StringUtils.replace(cssText, "; ", ";\n "); - cssText = REPLACEMENT_1.matcher(cssText).replaceFirst("font-family: \"$1\";"); - cssText = REPLACEMENT_2.matcher(cssText).replaceFirst("src: url(\"$1\");"); + if (getBrowserVersion().hasFeature(CSS_FONTFACERULE_CSSTEXT_CRLF)) { + cssText = StringUtils.replace(cssText, "{", "{\r\n\t"); + cssText = StringUtils.replace(cssText, "}", ";\r\n}\r\n"); + cssText = StringUtils.replace(cssText, "; ", ";\r\n\t"); + } + else { + cssText = StringUtils.replace(cssText, "{", "{\n "); + cssText = StringUtils.replace(cssText, "}", ";\n}"); + cssText = StringUtils.replace(cssText, "; ", ";\n "); + cssText = REPLACEMENT_1.matcher(cssText).replaceFirst("font-family: \"$1\";"); + cssText = REPLACEMENT_2.matcher(cssText).replaceFirst("src: url(\"$1\");"); + } return cssText; } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -18,6 +18,7 @@ import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_PIXEL_VALUES_INT_ONLY; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_SET_NULL_THROWS; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_SUPPORTS_BEHAVIOR_PROPERTY; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_TYPE_INTEGER; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_TYPE_NUMBER; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_UNDEFINED_FORCES_RESET; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_ZINDEX_UNDEFINED_OR_NULL_THROWS_ERROR; @@ -3877,6 +3878,15 @@ @JsxGetter public Object getZIndex() { final String value = getStyleAttribute(Z_INDEX); + if (getBrowserVersion().hasFeature(CSS_ZINDEX_TYPE_INTEGER)) { + try { + return Integer.valueOf(value); + } + catch (final NumberFormatException e) { + return ""; + } + } + if (getBrowserVersion().hasFeature(CSS_ZINDEX_TYPE_NUMBER)) { if (value == null || Context.getUndefinedValue().equals(value) @@ -3929,7 +3939,7 @@ return; } - // numeric (IE) + // number if (getBrowserVersion().hasFeature(CSS_ZINDEX_TYPE_NUMBER)) { final Double d; if (zIndex instanceof Double) { @@ -3947,7 +3957,7 @@ return; } - // string (FF) + // string if (zIndex instanceof Number) { final Number number = (Number) zIndex; if (number.doubleValue() % 1 == 0) { Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -34,6 +34,10 @@ * @author Ahmed Ashour * @author Frank Danek * + * @see <a href="http://www.w3.org/TR/DOM-Parsing/">W3C Spec</a> + * @see <a href="http://domparsing.spec.whatwg.org/">WhatWG Spec</a> + * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">Mozilla Developer Network</a> + * @see <a href="http://msdn.microsoft.com/en-us/library/ff975060.aspx">MSDN</a> * @see <a href="http://www.xulplanet.com/references/objref/DOMParser.html">XUL Planet</a> */ @JsxClass(browsers = { @WebBrowser(CHROME), @WebBrowser(FF), @WebBrowser(value = IE, minVersion = 11) }) @@ -48,17 +52,23 @@ } /** - * The string passed in is parsed into a DOM document. - * @param str the UTF16 string to be parsed - * @param contentType the content type of the string - - * either <tt>text/xml</tt>, <tt>application/xml</tt>, or <tt>application/xhtml+xml</tt>. Must not be NULL. + * Parses the given Unicode string into a DOM document. + * @param str the Unicode string to be parsed + * @param type the MIME type of the string - + * <code>text/html</code>, <code>text/xml</code>, <code>application/xml</code>, + * <code>application/xhtml+xml</code>, <code>image/svg+xml</code>. Must not be <code>null</code>. * @return the generated document */ @JsxFunction - public XMLDocument parseFromString(final String str, final Object contentType) { - if (Undefined.instance == contentType) { - throw Context.reportRuntimeError("Missing 'contentType' parameter"); + public XMLDocument parseFromString(final String str, final Object type) { + if (type == null || Undefined.instance == type) { + throw Context.reportRuntimeError("Missing 'type' parameter"); } + if (!"text/html".equals(type) && !"text/xml".equals(type) && !"application/xml".equals(type) + && !"application/xhtml+xml".equals(type) && !"image/svg+xml".equals(type)) { + throw Context.reportRuntimeError("Invalid 'type' parameter: " + type); + } + final XMLDocument document = new XMLDocument(); document.setParentScope(getParentScope()); document.setPrototype(getPrototype(XMLDocument.class)); Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLDocument.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLDocument.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLDocument.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -2167,8 +2167,17 @@ if (response instanceof FunctionObject && ("querySelectorAll".equals(name) || "querySelector".equals(name)) && getBrowserVersion().hasFeature(QUERYSELECTORALL_NOT_IN_QUIRKS)) { - final ScriptableObject sobj = getPage().getScriptObject(); - if ((sobj instanceof HTMLDocument) && ((HTMLDocument) sobj).getDocumentMode() < 8) { + Document document = null; + final HtmlPage page = getHtmlPageOrNull(); + if (page != null) { + document = (Document) page.getScriptObject(); + } + else if (start instanceof DocumentProxy) { + // if in prototype no domNode is set -> use start + document = ((DocumentProxy) start).getDelegee(); + } + if (document != null && document instanceof HTMLDocument + && ((HTMLDocument) document).getDocumentMode() < 8) { return NOT_FOUND; } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -17,6 +17,7 @@ import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_ERRORHANDLER_NOT_SUPPORTED; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_FIRE_STATE_OPENED_AGAIN_IN_ASYNC_MODE; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_IGNORE_PORT_FOR_SAME_ORIGIN; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_NO_CROSS_ORIGIN_TO_ABOUT; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_ONREADYSTATECANGE_SYNC_REQUESTS_COMPLETED; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_ONREADYSTATECANGE_SYNC_REQUESTS_NOT_TRIGGERED; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XHR_ONREADYSTATECHANGE_WITH_EVENT_PARAM; @@ -495,6 +496,9 @@ try { final URL fullUrl = containingPage_.getFullyQualifiedUrl(url); final URL originUrl = containingPage_.getUrl(); + if (!isAllowCrossDomainsFor(originUrl, fullUrl)) { + throw Context.reportRuntimeError("Access to restricted URI denied"); + } final WebRequest request = new WebRequest(fullUrl, getBrowserVersion().getXmlHttpRequestAcceptHeader()); request.setCharset("UTF-8"); @@ -536,6 +540,16 @@ setState(STATE_OPENED, null); } + private boolean isAllowCrossDomainsFor(final URL originUrl, final URL newUrl) { + final BrowserVersion browser = getBrowserVersion(); + if (browser.hasFeature(XHR_NO_CROSS_ORIGIN_TO_ABOUT) + && "about".equals(newUrl.getProtocol())) { + return false; + } + + return true; + } + private boolean isSameOrigin(final URL originUrl, final URL newUrl) { if (!originUrl.getHost().equals(newUrl.getHost())) { return false; Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HTMLParser4Test.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HTMLParser4Test.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/HTMLParser4Test.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -47,7 +47,8 @@ @Test @Alerts("TABLE") public void table_tfoot() throws Exception { - final String html = "<html><body>" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><body>" + "<table><tr><td>hello</td></tr>\n" + "<tfoot id='tf'><tr><td>foot</td></tr></tfoot>" + "</table>\n" @@ -67,8 +68,8 @@ @Test @Alerts("myForm") public void badlyFormedHTML() throws Exception { - final String html - = "<html><head><title>first</title>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>first</title>\n" + " <script>\n" + " function test(){\n" + " alert(document.getElementById('myInput').form.id);\n" @@ -98,8 +99,8 @@ // Note: the <meta> tag in this test is quite important because // I could adapt the TagBalancer to make it work except with this <meta http-equiv... // (it worked with <meta name=...) - final String html - = "<html><head><mainA3>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><mainA3>\n" + " <meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1'>\n" + " <title>first</title>\n" + " <script>\n" @@ -120,8 +121,8 @@ @Test @Alerts({"false", "true" }) public void duplicatedAttribute() throws Exception { - final String html - = "<html><head>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>\n" + "</head>\n" + " <script>\n" + " function test() {\n" @@ -146,8 +147,8 @@ IE8 = { "1", "3", "[object HTMLScriptElement]", "[object HTMLGenericElement]", "[object HTMLGenericElement]", "[object HTMLFormElement]" }) public void namespace() throws Exception { - final String html - = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" + "<html xmlns='http://www.w3.org/1999/xhtml' xmlns:app='http://www.appcelerator.org'>\n" + "<head>\n" + "<script>\n" @@ -180,11 +181,11 @@ "[object HTMLUnknownElement]", "APP:SCRIPT,APP:SCRIPT,http://www.w3.org/1999/xhtml,null,app:script" }, IE8 = { "1", "createElementNS() is not defined", - "[object]", "SCRIPT,SCRIPT,undefined,undefined,undefined", - "[object]", "script,script,undefined,undefined,undefined" }) + "[object HTMLScriptElement]", "SCRIPT,SCRIPT,undefined,undefined,undefined", + "[object HTMLGenericElement]", "script,script,undefined,undefined,undefined" }) public void namespace2() throws Exception { - final String html - = "<html xmlns='http://www.w3.org/1999/xhtml' xmlns:app='http://www.appcelerator.org'>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html xmlns='http://www.w3.org/1999/xhtml' xmlns:app='http://www.appcelerator.org'>\n" + "<head>\n" + "<script>\n" + " function test() {\n" @@ -232,8 +233,8 @@ // This is pretty mysterious because the second title HAS the text 'Inner Html' inside. // Currently I do not know why it behaves this way so I take the default behavior. public void completeHtmlInsideDiv() throws Exception { - final String html - = "<html><head>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>\n" + " <title>Outer Html</title>\n" + " <script>\n" + " function test() {\n" @@ -294,8 +295,8 @@ // This is pretty mysterious because the second title HAS the text 'Inner Html' inside. // Currently I do not know why it behaves this way so I take the default behavior. public void writeCompleteHtmlInsideDIV() throws Exception { - final String html - = "<html><head>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>\n" + " <title>Outer Html</title>\n" + " <script>\n" + " function test() {\n" @@ -348,8 +349,8 @@ "bodyTitles", "innerDiv", "outerDiv" }) public void setCompleteHtmlToDIV_innerHTML() throws Exception { - final String html - = "<html><head>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>\n" + " <title>Outer Html</title>\n" + " <script>\n" + " function test() {\n" @@ -402,8 +403,8 @@ @NotYetImplemented({ CHROME, FF, IE11 }) // currently the content of HEAD and BODY are added directly to HTML public void setCompleteHtmlToHTML_innerHTML() throws Exception { - final String html - = "<html><head>\n" + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>\n" + " <title>Outer Html</title>\n" + " <script>\n" + " function test() {\n" Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/IEConditionalCommentExpressionEvaluatorTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/IEConditionalCommentExpressionEvaluatorTest.java 2014-01-27 07:46:38 UTC (rev 9073) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/html/IEConditionalCommentExpressionEvaluatorTest.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -14,16 +14,12 @@ */ package com.gargoylesoftware.htmlunit.html; -import static com.gargoylesoftware.htmlunit.html.IEConditionalCommentExpressionEvaluator.evaluate; - -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.SimpleWebTestCase; +import com.gargoylesoftware.htmlunit.WebDriverTestCase; /** * Tests for {@link IEConditionalCommentExpressionEvaluator}. @@ -32,331 +28,384 @@ * @version $Revision$ * @author Marc Guillemot * @author Ahmed Ashour + * @author Frank Danek */ @RunWith(BrowserRunner.class) -public class IEConditionalCommentExpressionEvaluatorTest extends SimpleWebTestCase { +public class IEConditionalCommentExpressionEvaluatorTest extends WebDriverTestCase { /** * Test for expression [if IE]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void IE() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void IE() throws Exception { doTest("IE"); } /** * Test for expression [if IE 5]. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void IE_5() { + @Alerts("done") + public void IE_5() throws Exception { doTest("IE 5"); } /** * Test for expression [if IE 6]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void IE_6() { + @Alerts("done") + public void IE_6() throws Exception { doTest("IE 6"); } /** * Test for expression [if IE 7]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void IE_7() { + @Alerts("done") + public void IE_7() throws Exception { doTest("IE 7"); } /** * Test for expression [if IE 8]. + * @throws Exception if the test fails */ @Test - @Alerts(IE8 = "true", IE = "false") - public void IE_8() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void IE_8() throws Exception { doTest("IE 8"); } /** * Test for expression [if !IE]. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void notIE() { + @Alerts("done") + public void notIE() throws Exception { doTest("!IE"); } /** * Test for expression [if lt IE 5.5]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false", FF = "true") - public void lt_IE_5_5() { + @Alerts("done") + public void lt_IE_5_5() throws Exception { doTest("lt IE 5.5"); } /** * Test for expression [if lt IE 6]. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void lt_IE_6() { + @Alerts("done") + public void lt_IE_6() throws Exception { doTest("lt IE 6"); } /** * Test for expression [if lt IE 7]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void lt_IE_7() { + @Alerts("done") + public void lt_IE_7() throws Exception { doTest("lt IE 7"); } /** * Test for expressions [if lt IE 8]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void lt_IE_8() { + @Alerts("done") + public void lt_IE_8() throws Exception { doTest("lt IE 8"); } /** * Test for expression [if lt IE 9]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void lt_IE_9() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void lt_IE_9() throws Exception { doTest("lt IE 9"); } /** * Test for expression [if gt IE 5.5]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void gt_IE_5_5() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gt_IE_5_5() throws Exception { doTest("gt IE 5.5"); } /** * Test for expression [if gt IE 6]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "true") - public void gt_IE_6() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gt_IE_6() throws Exception { doTest("gt IE 6"); } /** * Test for expression [if gt IE 7]. + * @throws Exception if the test fails */ @Test - @Alerts(IE8 = "true", IE = "false") - public void gt_IE_7() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gt_IE_7() throws Exception { doTest("gt IE 7"); } /** * Test for expression [if gt IE 8]. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void gt_IE_8() { + @Alerts("done") + public void gt_IE_8() throws Exception { doTest("gt IE 8"); } /** * Test for expression [if gte IE 5.5]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void gte_IE_5_5() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gte_IE_5_5() throws Exception { doTest("gte IE 5.5"); } /** * Test for expression [if gte IE 6]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void gte_IE_6() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gte_IE_6() throws Exception { doTest("gte IE 6"); } /** * Test for expressions [if gte IE 7]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "true") - public void gte_IE_7() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gte_IE_7() throws Exception { doTest("gte IE 7"); } /** * Test for expressions [if gte IE 8]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "true") - public void gte_IE_8() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void gte_IE_8() throws Exception { doTest("gte IE 8"); } /** * Test for expressions [if !(IE 5)]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void parenthese_5() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void parenthese_5() throws Exception { doTest("!(IE 5)"); } /** * Test for expressions [if !(IE 6)]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "true") - public void parenthese_6() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void parenthese_6() throws Exception { doTest("!(IE 6)"); } /** * Test for expressions [if !(IE 7)]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "true") - public void parenthese_7() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void parenthese_7() throws Exception { doTest("!(IE 7)"); } /** * Test for expressions [if !(IE 8)]. + * @throws Exception if the test fails */ @Test - @Alerts(IE8 = "false", IE = "true") - public void parenthese_8() { + @Alerts("done") + public void parenthese_8() throws Exception { doTest("!(IE 8)"); } /** * Test for expressions [(gt IE 6)&(lt IE 8)]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void and() { + @Alerts("done") + public void and() throws Exception { doTest("(gt IE 6)&(lt IE 8)"); } /** * Test for expressions [if (IE 6)|(IE 7)]. + * @throws Exception if the test fails */ @Test - @Alerts(IE = "false") - public void or() { + @Alerts("done") + public void or() throws Exception { doTest("(IE 6)|(IE 7)"); } /** * Test for expressions [if true]. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void true_() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void true_() throws Exception { doTest("true"); } /** * Test for expressions [if false]. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void false_() { + @Alerts("done") + public void false_() throws Exception { doTest("false"); } /** * Test for expressions with "mso" (HTML code generated by MS Office). + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void mso_1() { + @Alerts("done") + public void mso_1() throws Exception { doTest("mso 9"); } /** * Test for expressions with "mso" (HTML code generated by MS Office). + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void mso_2() { + @Alerts("done") + public void mso_2() throws Exception { doTest("gte mso 9"); } /** * Test for expressions with "mso" (HTML code generated by MS Office). + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void mso_3() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void mso_3() throws Exception { doTest("lt mso 9"); } /** * Test for expressions with "mso" (HTML code generated by MS Office). + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void mso_4() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void mso_4() throws Exception { doTest("lt mso 1"); } /** * Test for expressions with unexpected identifier. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void unknown_1() { + @Alerts("done") + public void unknown_1() throws Exception { doTest("foo 1"); } /** * Test for expressions with unexpected identifier. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void unknown_2() { + @Alerts("done") + public void unknown_2() throws Exception { doTest("gte foo 1"); } /** * Test for expressions with unexpected identifier. + * @throws Exception if the test fails */ @Test - @Alerts("false") - public void unknown_3() { + @Alerts("done") + public void unknown_3() throws Exception { doTest("gt foo 1"); } /** * Test for expressions with unexpected identifier. + * @throws Exception if the test fails */ @Test - @Alerts("true") - public void unknown_4() { + @Alerts(DEFAULT = "done", + IE8 = { "cond", "done" }) + public void unknown_4() throws Exception { doTest("lt foo 1"); } - private void doTest(final String expression) { - final BrowserVersion browserVersion = getBrowserVersion(); - if (browserVersion.isIE()) { - final String expected = getExpectedAlerts()[0]; - Assert.assertEquals(expression + " for " + browserVersion.getNickname(), - expected, Boolean.toString(evaluate(expression, browserVersion))); - } + private void doTest(final String expression) throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head>" + + "<!--[if " + expression + "]><script>alert('cond');</script><![endif]-->\n" + + "<script>alert('done');</script>\n" + + "</head><body></body></html>"; + loadPageWithAlerts2(html); } } Added: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable2Test.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable2Test.java (rev 0) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable2Test.java 2014-01-27 17:15:00 UTC (rev 9074) @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2002-2014 Gargoyle Software Inc. + * + * Licensed 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. + */ +package com.gargoylesoftware.htmlunit.javascript; + +import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.CHROME; +import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.FF; +import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.FF24; +import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.IE11; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.gargoylesoftware.htmlunit.BrowserRunner; +import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; +import com.gargoylesoftware.htmlunit.BrowserRunner.Browsers; +import com.gargoylesoftware.htmlunit.BrowserRunner.NotYetImplemented; +import com.gargoylesoftware.htmlunit.WebDriverTestCase; +import com.gargoylesoftware.htmlunit.html.HtmlPageTest; + +/** + * Tests for {@link SimpleScriptable}. + * + * @version $Revision$ + * @author <a href="mailto:mb...@Ga...">Mike Bowler</a> + * @author <a href="mailto:Bar...@us...">Barnaby Court</a> + * @author David K. Taylor + * @author <a href="mailto:bc...@es...">Ben Curren</a> + * @author Marc Guillemot + * @author Chris Erskine + * @author Ahmed Ashour + * @author Sudhan Moghe + * @author <a href="mailto:mi...@10...">Mike Dirolf</a> + * @author Frank Danek + */ +@RunWith(BrowserRunner.class) +public class SimpleScriptable2Test extends WebDriverTestCase { + + /** + * This test fails on IE and FF but not by HtmlUnit because according to Ecma standard, + * attempts to set read only properties should be silently ignored. + * Furthermore document.body = document.body will work on FF but not on IE + * @throws Exception if the test fails + */ + @Test + @Alerts("exception") + public void setNonWritableProperty() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " try {\n" + + " document.body = 123456;\n" + + " } catch (e) { alert('exception'); }\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = "[object Arguments]", + IE8 = "[object Object]") + public void arguments_toString() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " alert(arguments);\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts("3") + public void stringWithExclamationMark() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var x = '<!>';\n" + + " alert(x.length);\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Test the host class names match the Firefox (w3c names). + * @see <a + * href="http://java.sun.com/j2se/1.5.0/docs/guide/plugin/dom/org/w3c/dom/html/package-summary.html">DOM API</a> + * @throws Exception if the test fails + */ + @Test + @Browsers({ CHROME, FF, IE11 }) + @Alerts(DEFAULT = "[object HTMLAnchorElement]", + CHROME = "function HTMLAnchorElement() { [native code] }", + FF24 = "function HTMLAnchorElement() {\n [native code]\n}", + IE8 = "[object]") + @NotYetImplemented({ CHROME, FF24 }) + public void hostClassNames() throws Exception { + testHostClassNames("HTMLAnchorElement"); + } + + private void testHostClassNames(final String className) throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " alert(" + className + ");\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Blocked by Rhino bug 419090 (https://bugzilla.mozilla.org/show_bug.cgi?id=419090). + * @throws Exception if the test fails + */ + @Test + @Alerts({ "x1", "x2", "x3", "x4", "x5" }) + public void arrayedMap() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var map = {};\n" + + " map['x1'] = 'y1';\n" + + " map['x2'] = 'y2';\n" + + " map['x3'] = 'y3';\n" + + " map['x4'] = 'y4';\n" + + " map['x5'] = 'y5';\n" + + " for (var i in map) {\n" + + " alert(i);\n" + + " }" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Browsers({ CHROME, FF, IE11 }) + @Alerts(CHROME = { "Node>Element: true", "Document>XMLDocument: true", "Node>XPathResult: false", + "Element>HTMLElement: true", "HTMLElement>HTMLHtmlElement: true", + "CSSStyleDeclaration>ComputedCSSStyleDeclaration: exception", "Image>HTMLImageElement: false", + "HTMLImageElement>Image: true" }, + FF17 = { "Node>Element: true", "Document>XMLDocument: true", "Node>XPathResult: false", + "Element>HTMLElement: true", "HTMLElement>HTMLHtmlElement: true", + "CSSStyleDeclaration>ComputedCSSStyleDeclaration: exception", "Image>HTMLImageElement: false", + "HTMLImageElement>Image: false" }, + FF24 = { "Node>Element: true", "Document>XMLDocument: true", "Node>XPathResult: false", + "Element>HTMLElement: true", "HTMLElement>HTMLHtmlElement: true", + "CSSStyleDeclaration>ComputedCSSStyleDeclaration: exception", "Image>HTMLImageElement: true", + "HTMLImageElement>Image: true" }, + IE11 = { "Node>Element: true", "Document>XMLDocument: true", "Node>XPathResult: exception", + "Element>HTMLElement: true", "HTMLElement>HTMLHtmlElement: true", + "CSSStyleDeclaration>ComputedCSSStyleDeclaration: exception", "Image>HTMLImageElement: true", + "HTMLImageElement>Image: true" }) + @NotYetImplemented({ CHROME, FF, IE11 }) + // TODO Class ComputedCSSStyleDeclaration is unknown in all real browsers + public void isParentOf() throws Exception { + final String[] expectedAlerts = getExpectedAlerts(); + + isParentOf("Node", "Element", expectedAlerts[0]); + isParentOf("Document", "XMLDocument", expectedAlerts[1]); + isParentOf("Node", "XPathResult", expectedAlerts[2]); + isParentOf("Element", "HTMLElement", expectedAlerts[3]); + isParentOf("HTMLElement", "HTMLHtmlElement", expectedAlerts[4]); + isParentOf("CSSStyleDeclaration", "ComputedCSSStyleDeclaration", expectedAlerts[5]); + + //although Image != HTMLImageElement, they seem to be synonyms!!! + isParentOf("Image", "HTMLImageElement", expectedAlerts[6]); + isParentOf("HTMLImageElement", "Image", expectedAlerts[7]); + } + + private void isParentOf(final String object1, final String object2, final String status) throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " try {\n" + + " alert('" + object1 + ">" + object2 + ": ' + isParentOf(" + object1 + ", " + object2 + "));\n" + + " } catch(e) { alert('" + object1 + ">" + object2 + ": exception'); }\n" + + " }\n" + + " /**\n" + + " * Returns true if o1 prototype is parent/grandparent of o2 prototype\n" + + " */\n" + + " function isParentOf(o1, o2) {\n" + + " o1.prototype.myCustomFunction = function() {};\n" + + " return o2.prototype.myCustomFunction != undefined;\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + setExpectedAlerts(status); + loadPageWithAlerts2(html); + } + + /** + * This is related to HtmlUnitContextFactory.hasFeature(Context.FEATURE_PARENT_PROTO_PROPERTIES). + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = "true", + IE8 = "false") + public void parentProtoFeature() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>First</title><script>\n" + + " function test() {\n" + + " alert(document.createElement('div').__proto__ != undefined);\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Test for http://sourceforge.net/p/htmlunit/bugs/587/. + * See also http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/browse_thread/thread/1f1c24f58f662c58. + * @throws Exception if the test fails + */ + @Test + @Alerts("1") + public void passFunctionAsParameter() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>First</title><script>\n" + + " function run(fun) {\n" + + " fun('alert(1)');\n" + + " }\n" + + "\n" + + " function test() {\n" + + " run(eval);\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Test JavaScript: 'new Date().getTimezoneOffset()' compared to java.text.SimpleDateFormat.format(). + * + * @throws Exception if the test fails + */ + @Test + public void dateGetTimezoneOffset() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var offset = Math.abs(new Date().getTimezoneOffset());\n" + + " var timezone = '' + (offset/60);\n" + + " if (timezone.length == 1)\n" + + " timezone = '0' + timezone;\n" + + " alert(timezone);\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + final String timeZone = new SimpleDateFormat("Z").format(Calendar.getInstance().getTime()); + final String hour = timeZone.substring(1, 3); + String strMinutes = timeZone.substring(3, 5); + final int minutes = Integer.parseInt(strMinutes); + final StringBuilder sb = new StringBuilder(); + if (minutes != 0) { + sb.append(hour.substring(1)); + strMinutes = String.valueOf((double) minutes / 60); + strMinutes = strMinutes.substring(1); + sb.append(strMinutes); + } + else { + sb.append(hour); + } + setExpectedAlerts(sb.toString()); + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({ "true", "function", "function" }) + public void callee() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + "function test() {\n" + + " var fun = arguments.callee.toString();\n" + + " alert(fun.indexOf('test()') != -1);\n" + + " alert(typeof arguments.callee);\n" + + " alert(typeof arguments.callee.caller);\n" + + "}\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = "[object HTMLDivElement]", + IE8 = "[object]") + public void getDefaultValue() throws Exception { + ... [truncated message content] |