diff --git a/doc/manual/src/docs/asciidoc/140-project.adoc b/doc/manual/src/docs/asciidoc/140-project.adoc index 44cb83ef7..28de6f3a1 100644 --- a/doc/manual/src/docs/asciidoc/140-project.adoc +++ b/doc/manual/src/docs/asciidoc/140-project.adoc @@ -94,6 +94,10 @@ This page lists the high level changes between versions of Geb. * Add support to provide more information for UnexpectedPageException. [issue:596[]] * Add integration with LambdaTest. [issue:603[]] +==== Fixes + +* `BindingUpdater` is not forwarding methods from `geb.textmatching.TextMatchingSupport` onto the `Browser` instance. [issue:601[]] + ==== Improvements * Improve integration between cloud browser gradle plugins and driver factories. [issue:579[]] diff --git a/module/geb-core/src/main/groovy/geb/binding/BindingUpdater.groovy b/module/geb-core/src/main/groovy/geb/binding/BindingUpdater.groovy index 38cc8e138..66750da0a 100644 --- a/module/geb-core/src/main/groovy/geb/binding/BindingUpdater.groovy +++ b/module/geb-core/src/main/groovy/geb/binding/BindingUpdater.groovy @@ -24,11 +24,34 @@ import geb.PageEventListenerSupport class BindingUpdater { static public final FORWARDED_BROWSER_METHODS = [ - "go", "to", "via", "at", - "waitFor", + "getPage", "getDriver", "getAugmentedDriver", "getNavigatorFactory", "getConfig", "getSessionStorage", "getLocalStorage", "getBaseUrl", "getCurrentUrl", "getJs", + "getAvailableWindows", "getCurrentWindow", "getReportGroupDir", + "setDriver", "setBaseUrl", + "go", "to", "via", + "at", "isAt", "verifyAtImplicitly", "checkIfAtAnUnexpectedPage", "createPage", + "pause", + "withWindow", "withNewWindow", + "report", "reportGroup", "cleanReportGroupDir", + "registerPageChangeListener", "removePageChangeListener", + "clearCookies", "clearCookiesQuietly", "clearWebStorage", + "close", "quit" + ].asImmutable() + + static public final FORWARDED_PAGE_METHODS = [ + "init", + /$/, "find", + "module", + "contains", "iContains", "notContains", "iNotContains", "endsWith", "iEndsWith", "notEndsWith", "iNotEndsWith", "containsWord", "iContainsWord", "notContainsWord", "iNotContainsWord", + "startsWith", "iStartsWith", "notStartsWith", "iNotStartsWith", + "withFrame", + "getOwner", "getPageFragment", "getRootContainer", "getContentNames", "getShouldVerifyAtImplicitly", "getAtVerificationResult", "getTitle", "getContentPath", "getContent", "getPageUrl", + "getBrowser", "getNavigator", + "onLoad", "onUnload", + "verifyAt", "verifyAtSafely", + "waitFor", "refreshWaitFor", + "focused", "interact", "convertToPath", "withAlert", "withNoAlert", "withConfirm", "withNoConfirm", - "download", "downloadStream", "downloadText", "downloadBytes", "downloadContent", - "report", "reportGroup", "cleanReportGroupDir" + "download", "downloadStream", "downloadText", "downloadBytes", "downloadContent" ].asImmutable() final Browser browser @@ -50,6 +73,7 @@ class BindingUpdater { BindingUpdater initialize() { binding.browser = browser binding.js = browser.js + binding.config = browser.config FORWARDED_BROWSER_METHODS.each { binding.setVariable(it, new InvocationForwarding(it, browser)) @@ -70,6 +94,7 @@ class BindingUpdater { binding.variables.remove('browser') binding.variables.remove('js') + binding.variables.remove('config') FORWARDED_BROWSER_METHODS.each { binding.variables.remove(it) @@ -82,12 +107,16 @@ class BindingUpdater { @Override void pageWillChange(Browser browser, Page oldPage, Page newPage) { binding.setVariable("page", newPage) - binding.setVariable("\$", new InvocationForwarding("\$", newPage)) + FORWARDED_PAGE_METHODS.each { + binding.setVariable(it, new InvocationForwarding(it, newPage)) + } } void clearBinding() { binding.variables.remove("page") - binding.variables.remove("\$") + FORWARDED_PAGE_METHODS.each { + binding.variables.remove(it) + } } } diff --git a/module/geb-core/src/test/groovy/geb/binding/BindingUpdaterSpec.groovy b/module/geb-core/src/test/groovy/geb/binding/BindingUpdaterSpec.groovy index f98a3a05c..3bb00f4f0 100644 --- a/module/geb-core/src/test/groovy/geb/binding/BindingUpdaterSpec.groovy +++ b/module/geb-core/src/test/groovy/geb/binding/BindingUpdaterSpec.groovy @@ -15,6 +15,8 @@ */ package geb.binding +import geb.Browser +import geb.Initializable import geb.Page import geb.test.GebSpecWithCallbackServer @@ -108,6 +110,50 @@ class BindingUpdaterSpec extends GebSpecWithCallbackServer { thrown MissingMethodException } + def "all browser methods are delegated to"() { + given: + updater.initialize() + + when: + def notDelegatedMethods = findPublicInstanceNonInternalMethodNames(Browser) - binding.variables.keySet() + + then: + !notDelegatedMethods + } + + def "all page methods are delegated to"() { + given: + updater.initialize() + + when: + def notDelegatedMethods = findPublicInstanceNonInternalMethodNames(Page) - findPublicInstanceNonInternalMethodNames(Browser) - binding.variables.keySet() + + then: + !notDelegatedMethods + } + + def "only existing browser methods are delegated to"() { + when: + def extraDelegatedMethods = BindingUpdater.FORWARDED_BROWSER_METHODS - findPublicInstanceNonInternalMethodNames(Browser) + + then: + !extraDelegatedMethods + } + + def "only existing page methods are delegated to"() { + when: + def extraDelegatedMethods = BindingUpdater.FORWARDED_PAGE_METHODS - findPublicInstanceNonInternalMethodNames(Page) + + then: + !extraDelegatedMethods + } + + private Set findPublicInstanceNonInternalMethodNames(Class clazz) { + def ignoredMethods = Object.methods + GroovyObject.methods + Initializable.methods + def internalMethodNames = ignoredMethods*.name + ["methodMissing", "propertyMissing"] + def publicInstanceMethods = clazz.metaClass.methods.findAll { it.public && !it.static } + publicInstanceMethods*.name.toSet() - internalMethodNames + } } class BindingUpdaterSpecPage1 extends Page {