Is it possible to get intellisense to work with Geb page objects? - groovy

I am guessing this is more of a groovy issue due to the geb implementation, but I'm wondering if there is any way to get intellisense to work with the geb page objects. I am also new to Java/Groovy (primarily C# development in the past) so there could be some things I'm just not quite understanding. I'm using Intellij, but I'd be happy if there is any IDE that could give me what I wanted.
As far as I can tell, Geb's implementation is that they have a Browser Class with a Page property and any methods or properties that are executed without the context of a specific Page instance will at runtime trigger a MissingMethod or MissingProperty exception, which Geb handles and re-routes to a corresponding method or property in the Page class that is currently set via the Page property in the Browser Class.
What this means for development is that when we're creating test cases, the IDE is unaware of which page instance is the current Browser Page property, thus no intellisense.
We experimented with creating instances of the pages and explicitly calling them, and also making our helper functions within the page classes static, both of which led to other issues.
For our shop, this is pretty much a deal breaker, but before we give up I wanted to see if any Geb or Groovy experts could offer some advice on how to get intellisense working, or could give us an indication of whether it is even possible.
EDIT: I found within the geb documentation a section on Strong Typing and IDE support that looked promising: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support however, the examples provided fail. I pasted the example directly from geb documentation below, with comments showing where/why it fails:
HomePage homePage = browser.to HomePage //browser.to returns null, so this fails
homePage.loginButton.click()
LoginPage loginPage = browser.at LoginPage //browser.at returns boolean so this fails
SecurePage securePage = loginPage.login("user1", "password1")
//The only thing that I got to work, which seems messy is:
browser.to HomePage
HomePage homePage = browser.page
homePage.loginButton.click()

Ok... So, I had an old version of Geb somehow being pulled from my gradle cache. After fixing that problem and actually using Geb 0.9.2, the documented usage worked correctly: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support

Related

Myfaces CODI DefaultErrorView - examples anywhere?

I've seen a reference to a DefaultErrorView in Myfaces CODI but as usual the
documentation leaves everything to the imagination. I've really found CODI to be a
great JSF addon, but it would benefit such a lot from some examples.
Probably naively I was hoping to be able to catch the dreaded ViewExpiredException
with this code:
#Page(basePath = "/defaultErrorPage.xhtml")
public final class DefaultErrorPage extends DefaultErrorView {
}
...but all that happens after session timeout is that container security takes me
to the login page when I try to issue a get request (clicking on a h:link). Does
anyone know what I can do with this DefaultErrorView, anyone got an example?
Thanks!
In the JavaDoc of DefaultErrorView you see:
...
The class which extends this class will also be used as error-view in case of security violations
(if there is no special error-view configured via
{#link org.apache.myfaces.extensions.cdi.core.api.security.Secured#errorView()})
And in the Wiki you see e.g.:
#Secured
...
In case of a violation CODI will use the DefaultErrorView as navigation target (if configured).
...
and
(Security) Error pages
The following example shows how to create a default error page. It's just allowed to provide one default error page per application.
Instead of implementing ViewConfig it's required to implement the DefaultErrorView interface.
...
as well as the manual usage:
...
this.viewNavigationHandler.navigateTo(DefaultErrorView.class);
...
The Wiki also links a nice example and there you find:
http://code.google.com/a/apache-extras.org/p/myfaces-codi-examples/source/browse/community/src/main/java/org/apache/extras/myfaces/codi/examples/community/view/config/Pages.java
-> everything is fine with the documentation ;-)

Manually Invoke JSF Validation in Seam Test

I want to write integration tests for my application. I want to test, that the required=true attribute on my text components are set on some JSF Pages.
When extending SeamTest, I can simulate a FacesRequest, and here I can overwrite the processValidationsPhase. There is a bultin method called validateValue, but this is just for Hibernate Validator Validations. So how can I invoke JSF Validators manually? Has anyone done this successfully before?
Is searched the whole JBoss JIRA and the JBoss Forums for a solution, but did not find anything, besides that it was asked very often, but never answered :(
You can use Selenium (firefox add-on) for testing.
Once you have recorded the tests, you can export to plain Java code, and use it in your extended SeamTest class, making sure that the values ​​are required = true are in the request.
To learn more, see http://seleniumhq.org/projects/ide/

Getting data from the options page to the injected code

My extension runs on an existing web page I do not control. I want to have an options page for it. What I haven’t figured out is how to get the option values from the injected code. localStorage isn’t shared, of course. I’ve tried using sendRequest / addListener in both directions, although it would be much preferable to push values from the options page to the injected code than they other way ‘round.
At the beginning, I simply put the option checkboxes on the manipulated page (the one the code is injected into), and those checkboxes set values in localStorage:
localStorage.showStuff = !!$(evt.target).attr(‘checked’);
Then I check those values in the code:
if (localStorage.showStuff == ‘true’) { … }
I moved the checkbox code to the options page and had it do a sendRequest when the options changed, and had my injected code have a listener for the message, but it doesn’t get the messages (my background page does, but that doesn’t help me). I also tried having the injected code hand a callback to the options page, but the sendResponse object only seems to work for the duration of the notify handler (not surprising, but I had to give it a try).
Right now my manifest’s permissions lists the foreign page ("http://example.com/*") and “tab”.
The one thing I know I can do is asynchronously query the options page via a callback, but the code doesn’t (and really can’t) work asynchronously without serious rewriting.
Any and all ideas welcome, thanks in advance.
i'm new to chrome extensions but when i tried to write/read localstorage from both, background script and option page it worked perfectly.
i haven't tried native localstorage but chrome's storage api.
take a look at this
code A: (set)
chrome.storage.sync.set({'key':'qwe'});
code B: (get)
chrome.storage.sync.get('key', function(response) {
console.log(response); // 'qwe'
});
u could put either code A in the background and code B in the option page or the other way around.
they are using the same storage.
this works for me. i hope u'll get there too.
The thing to remember is that only the background page is long-lived. The rest of the pieces of your chrome extension are transient (content scripts for the duration of the site navigation, options pages only while open, etc).
So you have to use messaging and save things using the background page. However, get ready for the storage API which should be landing soon. This will make things a lot easier for you!
Check it out here.

Pharo: #subclass:instanceVariables... message personalized

I am fighting against the Object message #subclass:instanceVariableNames:classVariableNames:poolDictionaries:category, in order to manipulate subclasses of an specific class.
I have RareClass with a class method #subclass:coposes...etc and want to do:
RareClass
subclass: #RareSubclass
composes: #SomeMagic
instanceVariableNames: ''
classVariableNames: ''
in the browser.
whether this method should return a class, (and i think it does) it is not working at all, im getting parsing errors when i try to 'save'...
I guess you are using OmniBrowser with the Refactoring Engine loaded?
The Refactoring Engine enforces the standard class templates to enable undo on any action performed in the browser. Obviously that cannot work with custom class definitions.
As a workaround you can do one of the following:
Use the traditional browser that has no undo functionality (evaluate Browser open),
Get rid of the refactoring functionality in OmniBrowser by unloading the package "OB-Reactory", or
Update the code in RBAddClassChange to support your use case.

How to use Geb to check element attribute value after page event

After a bit of help here, I am writing a functional web test using Geb and want to test the disabled attribute value of an form submit button both before and after an event has occurred, the flow should be as follows:
Load page, submit button is declared as disabled in page source so should be disabled e.g. <input type="submit" class="submit" disabled="true"/>.
Check a checkbox on the page, this should result in a piece of JQuery code executing which will enable the disabled submit button programatically using: $('input.submit').attr('disabled', false);
My first attempt was to use the assertion $('input.submit').#disabled == 'true', this appeared to work for the initial check after page load however after executing my JQuery code to enable the button a subsequent check still returns the same result. This has caused me to wonder if this kind of check is only able to report the value at page load time and doesn't see any subsequent programmatic changes?
I then discovered Geb's jquery itegration, I was hoping I could use this to return the value of the submit button and do my assert on this e.g. $('input.submit').jquery.attr('disabled') == false however the Geb documentation confirms that all calls to the .jquery property return the Geb Navigator instance so sadly I don't think I can return the information I want.
I have also doubted whether the JQuery code was actually toggling the submit button disabled state, I have tested this extensively using Firebug and can confirm that this is working perfectly in the browser, so I suspect this is either an issue with my understanding of Geb or perhaps a limitation of Geb itself?
It strikes me that checking the value of element attributes after performing some action on a page might be a common use-case, hence I'm rather hoping that I've missed some trivially simple way of doing this. Would be most grateful for any pointers to help me get this sorted.
Cheers,
Edd
Have done a bit more testing and have now achieved a satisfactory result. I was doing a couple of things which I now believe are inproper, namely trying to set the disabled attribute value to illegal values of true and false like this:
$('input.submit').attr('disabled', true);
$('input.submit').attr('disabled', false);
Looking at the HTML forms specification the disabled attribute is shown not to take a value, rather it's presence alone indicates that an element is disabled. Modifying my code to honour this and remove the attribute to indicate enablement of an element seems to have done the trick:
$('input.submit').attr('disabled', true);
//This time we remove the disabled attribute rather than setting it to false.
$('input.submit').removeAttr('disabled');
Note: I am still setting the value of disabled to true since I can't determine how to set the attribute without setting a value, see this SO post for further details.
Using the above I am now able to use Geb to assert the disabled/ enabled status of elements like this:
//Check that something is disabled.
deleteSelectedButton.#disabled == 'true'
//Check that something is enabled.
deleteSelectedButton.#disabled == 'false'
Note: Geb seems to require a string literal indicating the expected status rather than a boolean, which iirc caused my assertions to fail.
So that's it - all is now working nicely and I'm running along writing loads of Geb tests! Hope this explanation is of some use to others.
Rebroadcasting my post on the Geb mailing list:
After you execute the jQuery code that enables the button, is it possible that you are checking the result before the code has actually enabled the button? For example, are doing something like:
waitFor { $("input.submit").#disabled == "false" }

Resources