Watir: how to find iframe's tag? - watir

I have an element, for example #<Watir::IFrame:0x..f98fef949215c673e located=false selector={:element=>(webdriver element)}>. How do I determine what tag it is (iframe)?
Found it by searching for similar Javascript method: there exists element.tag_name, but when using it for iframe I get NoMethodError: private method 'tag_name' called for #<Watir::IFrame:0x00000002f8c288>'.
What does it mean and is there some alternative to .tag_name for iframes?

The exception means that the tag_name method is private for Watir::IFrame (and Watir::Frame) objects. "Private", along with "public" and "protected", methods are used for controlling access of methods within a class. The Ruby Pickaxe book has a good description of the method types:
Public methods can be called by anyone---there is no access control. Methods are public by default (except for initialize, which is always private).
Protected methods can be invoked only by objects of the defining class and its subclasses. Access is kept within the family.
Private methods cannot be called with an explicit receiver. Because you cannot specify an object when using them, private methods can be called only in the defining class and by direct descendents within that same object.
Ultimately, this means that you cannot call the tag_name from outside of the class.
Given that the Watir API allows calling the tag_name method for other element types, I would say it is a bug. A pull request has been opened to have the method made public Issue 293.
As a workaround, you can call private methods by using send:
browser.iframe.send('tag_name')
#=> "iframe"
Note that given you already have a Watir::IFrame object and depending on what you are trying to do, you might not need to check the tag name. You could check the class of the object instead:
browser.iframe.class
#=> Watir::IFrame

Related

Orchard: Welding a ContentPart to all ContentTypes

I have a requirement where i need to weld a ContentPart to all the content types. Please guide me what is the best place to write this code.
I looked into the Orchard source code where InfosetPart is being welded with all content types in ContentHandlerBase's Activating method.
Following the InfosetPart weld mechanism i created one class inheriting from ContentHandlerBase and in Activating method i placed a break point with following condition which is getting hit again and again (more than once for one content type)
context.ContentType == "Page"
I'm not sure if it should be as it is because ideally it should hit this condition only once.
The way you are implementing it is correct. Your code is executed multiple times because content handlers are invoked for each content item, and not just for the content type. This also allows you to weld your part to only some of you content items, not all items of a specified type.
You wrote that you created a subclass of ContentHandlerBase. You should use ContentHandler as a base class.
Below is a simple code example how this should be done.
public class MyPartHandler : ContentHandler
{
protected override void Activating(ActivatingContentContext context) {
context.Builder.Weld<MyPart>();
}
}

JavaFx: how to reference main Controller class instance from CustomComponentController class?

WHAT I HAVE is a standard JavaFX application: Main.java, MainController.java & main.fxml. To add custom component, I created CustomComponentController.java and custom_component_controller.fxml.
PROBLEM is that in CustomComponentController methods I need to reference other methods and standard components from MenuController. I add public static MainController mc; to MainController class body, so that it can be seen from CustomComponentController (MainController.mc.neededMethod()). Then I try to pass everything to it in MainController.initialize() method (mc = this;) - when debugging this breakpoint, I see this full of components instances, but mc remains with null components afterwards.
QUESTION is how to reference the running instance of MainController to use its components and methods in other classes and to crossreference different custom components from each other? How to clean MainController code from event handlers and assistance methods of components by moving it all to component's own class?
I tried the following approaches, but found no way to make them work without errors:
Accessing FXML controller class
How can I access a Controller class in JavaFx 2.0?
JavaFX 2.0 + FXML. Updating scene values from a different Task
JavaFX 2.2 -fx:include - how to access parent controller from child controller
The problem can be solved if you comply the following conditions:
Not only public, but obligatory static MainController mc should be.
Do not forget id in fxml for CustomComponentController: <CustomComponentController fx:id="cc"/>, where cc is the name of the "#FXML imported" CustomComponentController in your MainController class.
Omit parameter fx:controller="main.CustomComponentController" in custom_component_controller.fxml as it results in "Controller value already specified" error (a conflict between main.fxml and custom_component_controller.fxml markup declared controllers).
Put mc = this; in the beginning of MainController's initialize() method. Before using mc in CustomComponentController class, check if it's not null. It can be null when all components, including CustomComponentController, are instantiated at application startup, but there is no mc instance yet. MainController method initialize() where MainController is instantiated is called after components are loaded. Therefore better practice is to use approach in the next paragraph.
In main.fxml create primary component of the same type that CustomComponentController and with the only fx:id parameter. Replace primary component with your CustomComponentController by creating reloadCustomComponents() method and calling it from CustomComponentController's initialize() method. Do it by adding the following to reloadCustomComponents() method:
customComponentAnchorPane.getChildren().remove(customComponent);
customComponent = new customComponent();
customComponentAnchorPane.getChildren().add(customComponent);
Thus all components can be placed outside CustomComponentController with all their methods and reloaded at the startup of the apllication. All component declarations stay in MainController class and can be reached through MainController mc reference. No duplicate creating of components in detail with parameters is needed.
Your problem looks like the classic catalog-crud forms updating, I implemented an interface that I called Updatable with an update method so I could reference any catalog form with any crud form easy after passing Controller Main Class as the UserData Property of the Child Root Component's Form
Hope it Can Solve your problem

How to access a composite component's sibling via clientId

I have a composite component that bundles some input fields. The component will be used multiple times on a page and contains a button to copy the values of another of these components. For this I would need to access one of those siblings via its clientId as a target for an
<f:ajax execute=":XXX:siblingId" render="...">
My problem lies in constructing this ID. I have the name of the sibling and I can make sure that it is located in the same naming container as the component that contains the copy button, but I can't control the complete nesting hierarchy, so it might be :form:foo:bar:parent:child or just form:parent:child. So essentially I would want to get the prefix of the current composite component, but without the component's own ID and then attach the ID of the component from which to copy.
This is similar to these questions:
How to address the surrounding naming container in jsf
How to access the parent naming container of composite
However, both answers make use of PrimeFaces-sepcific features like #parent and widgetVar, which does not apply to my project.
When experimenting with EL's implicit objects I basically tried the same things as the poster of the second question - with the same results: cc.parent.clientId is always empty. I also tried cc.namingContainer.clientId and some combinations of the two, alas - no success. Especially the fact that parent does not work as expected confuses me...
So: Is there a component-library-agnostic way to access the "path" of containing naming containers for a composite component? How is the parent object supposed to work, especially: when can we use it and when not?
PS: I was thinking about using the composite's full clientId and then trimming its actual ID with fn:split, however, if there was a more direct way I'd be happy to use it.
The #{cc.parent} resolves to UIComponent#getCompositeComponentParent() which returns the closest parent composite component. In other words, it returns only non-null when the composite component is by itself nested in another composite component.
The #{cc.namingContainer} simply refers to #{cc} itself, fully conform as specified in UIComponent#getNamingContainer():
Starting with "this", return the closest component in the ancestry that is a NamingContainer or null if none can be found.
Composite components namely implicitly implement NamingContainer themselves.
So your attempts unfortunately won't work. I also do not see any "standard API" ways to achieve the concrete functional requirement. The CompositeComponentAttributesELResolver causes that the #{cc.parent} doesn't resolve to UIComponent#getParent() which is what you ultimately want.
You can however provide a custom UIComponent implementation for the composite which adds an extra getter with an unique name which in turn properly delegates to UIComponent#getParent().
Here's a kickoff example:
#FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {
public UIComponent getParentComponent() {
return super.getParent();
}
}
If you register it as follows in the composite interface:
<cc:interface componentType="myComposite">
then you'll be able to use
#{cc.parentComponent.clientId}
to get the client ID of the real parent UIComponent.
Ultimately you should be able to use the following construct to refer the sibling:
process=":#{cc.parentComponent.clientId}:siblingId"

How to override context.getUser()

for a my current project I would like to overide the context.getUser() method to return a custom pojo which extends the default object returned?
The reason I would like to do is so that I dont have to use the sessionScope technique of saving person specific data and just can call context.getUser() instead (which checks which user is logged on (or anonymous) and retrieves all data needed without.
I would not override context.getUser() - you don't know what else that may require. Have you looked at the userBean and or peopleBean from the extension library? You could use that to get any information you need, then if you need more, or want to create a custom class that extends those beans, install it as a scoped bean in your application, and then use it as the base for your own getUser().

How to access a method of another class(.cs)inside another ascx page(design page)

I have 1 method which returns the count of records,i want to access this method in design page(ascx) .how to do that?
If your method is in the code-behind class for the ascx then method needs to have public or protected (because ascx class will inherit from code behind class) - then you can use server directives or data binding to access the method - for example
<span><%= this.CallMyMethod() %></span>
or
<span><%# this.CallMyMethod() #></span>
For later (data-binding) syntax to work, you must call DataBind method on the parent(ancestor) control.
In case, your method is in another class and its instance method then you need to have instance of that class to call the method. Calling mechanism remains same as above except replace this keyword with the variable (instance) of another class. For static methods, you can invoke them using className.MethodName syntax. Note that the method has to be accessible from ascx (i.e. public or internal etc).

Resources