Can Module work withNewWindow?

62 views
Skip to first unread message

Yura Kalemi

unread,
Nov 21, 2018, 2:24:56 AM11/21/18
to Geb User Mailing List
I have some issue with Module - $ function dosn't work if I use browser.withNewWindow method.
There is little test case.

1. Tested geb.html. It has one button, wich opens another window
<html><head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Window Open Test</title>

  <script type="text/javascript">
    
function open_blank()
{
var w = window.open("about:blank", "_blank", "width=800,height=500,status=0,toolbar=0");
  w.document.write("<html><head></head><title>New Window</title><body><div id='divel'>div text</body></html>");
  w.document.close();
  w.focus();
}


</script>

</head>
<body>
  <button id="newwindow" onclick="open_blank()">
window open blank
</button>
</body></html>

2. SimplePage - doesn't use any Module

class SimplePage extends Page {
static url = 'file:///home/ykalemi/geb.html'

static at = { title == "Window Open Test" }

String getDivText() {
return browser.withNewWindow( {$('#newwindow').click()} ) {
return $('div', id: 'divel').text()
}
}
}

3. ModuledPage - has two kind of modules

class ModuledPage extends Page {
static url = 'http://localhost/geb.html'
static at = { title == "Window Open Test" }

static content = {
simpleWindowModule {module SimpleModule}

smartWindowModule {module SmartModule}
}
}

4. SimpleModule - module with $-function.

class SimpleModule extends Module {

String getDivText() {
return browser.withNewWindow( {$('#newwindow').click()} ) {
return $('div', id: 'divel').text()
}
}
}

5. SmartModule - module with workaround

class SmartModule extends Module {

String getDivText() {
return browser.withNewWindow( {$('#newwindow').click()} ) {
return browser.navigator.find('div', id: 'divel').text()
}
}
}

6. And Module
Spec

class ModuleSpec extends GebReportingSpec {

// pass
def 'PageInteraction'() {
when:
to SimplePage
then:
getDivText() == 'text'
}

// fails with NoSuchElementException: Web element reference not seen before: 4d4c610f-1366-4bc1-ad34-15f6326e336d
def 'SimpleModuleInteraction'() {
when:
to ModuledPage
then:
simpleWindowModule.getDivText() == 'text'
}

// pass
def 'SmartModuleInteraction'() {
when:
to ModuledPage
then:
smartWindowModule.getDivText() == 'text'
}
}


Looks like navigator inside Module cannot survive after page reloading / new window opening.
Is it a bug? Or am I misuse Module in this case?

Geb: 2.2
Spock: 1.1
Selenium: 3.14.0

Marcin Erdmann

unread,
Nov 21, 2018, 4:12:47 PM11/21/18
to geb-...@googlegroups.com
Hi Yura,

Yes, I'm afraid that you are indeed misusing Geb modules in this case.

The issue you are seeing is because calls to $() from within a module resolve the passed selectors relative to the base of the module (http://gebish.org/manual/current/#base-and-context). In your case the base of the module is located within the original window and then you are trying to resolve a selector relative to it from within the new window. The web element which is backing your module base does not exist in the new window hence the error you are getting mentions an element has not been seen before (that element is the module base which is in the original window).

The way to solve it is to model content of the newly opened window with a page class (see http://gebish.org/manual/current/#code-page-code-2) and use it from your module:

class NewWindowPage extends Page {
    static content = {
        divText { $('div', id: 'divel').text() }
    }
}

class SimpleModule extends Module {
    String getDivText() {
        return browser.withNewWindow({$('#newwindow').click() }, page: NewWindowPage) {
            return divText
        }
    }
}

--
You received this message because you are subscribed to the Google Groups "Geb User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to geb-user+u...@googlegroups.com.
To post to this group, send email to geb-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/geb-user/4e08e721-e895-4a4d-b2a3-73fe22e29c07%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yura Kalemi

unread,
Nov 22, 2018, 4:39:35 AM11/22/18
to Geb User Mailing List
Hi Marcin
Thank you for your attention!

But unfortunately it doesn't work too:

return browser.withNewWindow({$('#newwindow').click()}, page: NewWindowPage) {

   
return txtElement
}

(I have just renamed divText to txtElement just for avoid naming collision with method name)

Exception is:

simpleWindowModule.getDivText() == 'text'
|                  |
|                  groovy.lang.MissingPropertyException: Unable to resolve txtElement as content for ModuledPage -> simpleWindowModule: SimpleModule, or as a property on its Navigator context. Is txtElement a class you forgot to import?
ModuledPage -> simpleWindowModule: SimpleModule


As you can see - geb doesn't search for 
txtElement in NewWindowPage.

But if I change this code and take txtElement from current page - it will be okay (because NewWindowPage is really current page):

String getDivText() {
return browser.withNewWindow({$('#newwindow').click()}, page: NewWindowPage) {
        def page = browser.getPage()
return page.txtElement
}
}



четверг, 22 ноября 2018 г., 2:12:47 UTC+5 пользователь Marcin Erdmann написал:

Marcin Erdmann

unread,
Nov 22, 2018, 5:10:03 PM11/22/18
to geb-...@googlegroups.com
Right. This makes sense. It's because this is called from within a class extending module which defines propertyMissing() that throws a MissingPropertyException at the end if no matching property has been found.

I now see that using 'page:' option for withNewWindow() will only work as expected if it's called from within a test class. I think the delegate of the closure should be switched to the browser instance and the resolution strategy should be set to DELEGATE_FIRST. I've created an issue for this: https://github.com/geb/issues/issues/545. For the time being you will unfortunately have to stick to the workaround you provided.

Marcin

--
You received this message because you are subscribed to the Google Groups "Geb User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to geb-user+u...@googlegroups.com.
To post to this group, send email to geb-...@googlegroups.com.

Yura Kalemi

unread,
Nov 23, 2018, 1:33:53 AM11/23/18
to Geb User Mailing List
Marcin, thanks for your investigation.
Looking forward to the fix

пятница, 23 ноября 2018 г., 3:10:03 UTC+5 пользователь Marcin Erdmann написал:

Marcin Erdmann

unread,
Nov 23, 2018, 3:56:05 AM11/23/18
to geb-...@googlegroups.com
No worries. It's a pleasure to help when the problem reported comes with a high quality and detailed explanation showing both the problem at hand and what has been tried to overcome it.

Reply all
Reply to author
Forward
0 new messages