ElementFinder(ContextAware) class instantiation with SeleniumLibrary/robotframework? - robotframework

With Selenium2library, the following works fine (python):
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
elements = ElementFinder().find(browser, locator, tag)
But the same fails for SeleniumLibray, on investigating figured out that ElementFinder class in Seleniumlibrary has a parameter that needs to be passed (ctx). Could someone help me out what needs to be passed to instantiate ElementFinder() class?

The context is the instance of the library itself.
Example:
from robot.libraries.BuiltIn import BuiltIn
from SeleniumLibrary.locators import ElementFinder
def custom_keyword(locator):
selib = BuiltIn().get_library_instance("SeleniumLibrary")
ef = ElementFinder(selib)
element = ef.find(locator)
return element

Related

Python unittest Mock an object to not have an attribute

I have a function that runs some code if the object has a certain attribute, and in rare cases if if the object does not have the attribute, it runs different code. It is hard for me to create the object without the attribute for testing. I tried del instance.attribute but got an error. The attribute is actually a #property under the hood.
I have an object instance that has foo attribute. How does one mock it so that when one tries to access instance.foo it raises an AttributeError as usual if there is no attribute?
I tried mock.Mock(side_effect=AttributeError('Boom!')) but it only works with methods.
You could try to use a PropertyMock for the property, and generally you shall be able to set the respective side effect. Here is a simple working example:
from unittest import mock
import pytest
class Foo:
#property
def bar(self):
return "bar"
def test_no_foo():
bar_mock = mock.PropertyMock()
with mock.patch(f"{__name__}.Foo.bar", bar_mock):
bar_mock.side_effect = AttributeError('Boom!')
foo = Foo()
with pytest.raises(AttributeError):
foo.bar
As you patch the property in the class, not in the object, you can can also do this using patch.object if you have access to the object by accessing the class of the object:
def test_no_foo():
bar_mock = mock.PropertyMock()
foo = Foo()
with mock.patch.object(foo.__class__, "bar", bar_mock):
bar_mock.side_effect = AttributeError('Boom!')
with pytest.raises(AttributeError):
foo.bar

Creating a new instance of a KClass

I have a Kotlin class whose primary (and only) constructor is empty.
I have a reference to this class:
val kClass: KClass<MyClass> = MyClass::class
How do I create an instance of this class using reflection?
In Java I would do myClass.newInstance() but it seems in Kotlin I need to find the constructor first:
kClass.constructors.first().call()
I have seen mention of primaryConstructor in some bug reports but it's not showing up in my IDE.
In your case, Java reflection might be enough: you can use MyClass::class.java and create a new instance in the same way as you would with Java reflection (see #IngoKegel's answer).
But in case there's more than one constructor and you really need to get the primary one (not the default no-arg one), use the primaryConstructor extension function of a KClass<T>. It is a part of Kotlin reflection, which is not shipped within kotlin-stdlib.
To use it, you have to add kotlin-reflect as a dependency, e.g. a in Gradle project:
dependencies {
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
Assuming that there is ext.kotlin_version, otherwise replace $kotlin_version with the version you use.
Then you will be able to use primaryConstructor, for example:
fun <T : Any> construct(kClass: KClass<T>): T? {
val ctor = kClass.primaryConstructor
return if (ctor != null && ctor.parameters.isEmpty())
ctor.call() else
null
}
You can use the Java class to create new instance:
MyClass::class.java.newInstance()
For those checking this question now, since Kotlin 1.1 there's also createInstance() extension method on KClass
Much like the accepted answer, this function works only in case class has an empty constructor or constructor with all default arguments.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.full/create-instance.html
Expanding on Alexeys Answer, to include a primary constructor call with parameters:
/* Example class with no-args constructor */
class MyClass
/* Example class requiring parameters */
class MyClassWithParams(parameter1: String, parameter2: MyClass)
val myKClass: KClass<MyClass> = MyClass::class
val myKClassWithParameters: KClass<MyClassWithParams> = MyClassWithParams::class
/* We can create an object by calling createInstance when no constructor parameters are required as explained in other answers. */
val myObject: MyClass = myKClass.createInstance()
/* To create an object with parameters, we need to get the constructor first, and call it with the parameters instead, similarly to how we would do in Java. */
val myObjectWithParameters: MyClassWithParams? =
myKClassWithParameters.primaryConstructor?.call(
"StringParameter", myObject
)

Plone- In a dexterity.EditForm why is attempting to disable a widget causing a ConstraintNotSatisfied error?

I'm trying to disable a widget in a dexterity.EditForm, but I'm getting an error .
Here is a part of my interface class with the particular widget I want to disable
class IRestaurant(IPlace):
restaurant_code = schema.TextLine(title=_(u""),
required=False,
)
IPlace is a form.Schema that IRestaurant inherits from. (from plone.directives)
Here is the code I for the dexterity.EditForm class:
class Edit(dexterity.EditForm):
grok.context(IRestaurant)
def updateWidgets(self):
super(Edit, self).updateWidgets()
self.widgets['restaurant_code'].disabled = True
When I go to the edit form, I get an error:
ConstraintNotSatisfied: True
Why is this error occurring and how can I fix this?
Also, the version of Plone I am using is Plone 4.3.5.
Edit: When I tried printing the type of object that self.widgets['restaurant_code'].disabled was, it said it was a NoneType object.
You might have better luck using the mode property.
Try something like this:
from z3c.form.interfaces import HIDDEN_MODE
def updateWidgets(self):
super(Edit, self).updateWidgets()
self.widgets['restaurant_code'].mode = HIDDEN_MODE

Determine runmode in Adobe CQ

How do I programmatically know which run-mode the instance is running? I created a custom tag that provides the config depending on the instance run-mode, but I can not determine the current run-mode.
I found a method that returns a list of run-mods instance:
SlingSettings settings = ...get from BundleContext...
Set<String> currentRunModes = settings.getRunModes();
But I can not get the objects SlingSettings or BundleContext. How can I get these objects or perhaps there is another way to get the current run-mode?
SlingSetttings is the right way - If it's from Java the simplest way to get it is with an SCR #Reference annotation in a class that's an SCR #Component, saves you from having to go through BundleContext.
If it's from a Sling script, you can use sling.getService(....) to get the SlingSettings.
Note that the cases where you need to read the run modes are rare, usually you'd rather setup your OSGi configurations to depend on the run modes and have the OSGi components modify their behavior based on that.
Finally I decided to use global.jsp, write run-modes in the page context and get it in my class:
<%
pageContext.setAttribute("runModes", sling.getService(SlingSettingsService.class).getRunModes().toString());
%>
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.apache.sling.settings.SlingSettingsService;
public class myClass {
public static Set<String> getRunModes() {
BundleContext bundleContext = FrameworkUtil.getBundle(myClass.class).getBundleContext();
ServiceReference serviceReference = bundleContext.getServiceReference(SlingSettingsService.class.getName( ));
SlingSettingsService slingSettingsService = (SlingSettingsService)bundleContext.getService(serviceReference);
return slingSettingsService.getRunModes();
}
}
#Reference
RunMode runmode;
or
sling.getService( RunMode.class )
and call
getCurrentRunModes(); //returns String[]
If you're using Sightly and working with a class that extends WCMUsePojo
slingSettings =this.getSlingScriptHelper().getService(SlingSettingsService.class);
Set<String> runmodes = slingSettings.getRunModes();
As Bertrand Delacretaz said it is the right way to check whether instance is Author or Publish.
In jsp or java you could check like
import org.apache.sling.settings.SlingSettingsService
Set<String> runModes = sling.getService(SlingSettingsService.class).getRunModes();
if (runModes.contains("author")) {
}
Another way is using
if (mode == WCMMode.EDIT)
{
}
But this approach will fail in case of Preview mode and wouldn't work.
You can also try this:
RunModeService runModeService = getSlingScriptHelper().getService(RunModeService.class);
author = runModeService.isActive("author");

z3c.forms dynamic sources provider returns empty dictionary as a context object

I'm using Plone 4.1.4 and I'm trying to get dynamic sources for a schema.Choice to work, I need to populate country list which in turn depends on the context object.
I'm using this example:
http://plone.org/products/dexterity/documentation/manual/developer-manual/advanced/vocabularies
For IContextSourceBinder, example, an empty dictionary instead of actual context object is returned:
from zope import interface
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from zope.schema.interfaces import IContextSourceBinder
import zope.schema
from z3c.form import form
class CountryGenerator(object):
interface.implements(IContextSourceBinder)
def __call__(self, context):
#context is == {}
import pdb; pdb.set_trace()
return SimpleVocabulary([
SimpleTerm(value="not_selected", title=_("Country Not Selected"))
])
class IStep(interface.Interface):
region = schema.Choice(title=_("Select your country"),
required=True,
source=CountryGenerator,
default="not_selected")
class Step(form.Form):
fields = field.Fields(IStep)
label = _("Step")
description = _("Select your country")
When debugging point is hit inside CountryGenerator.__call__() method and I examine context object, the latter turn out to be just an empty dictionary.
When I try to use named utility example in the article mentioned above, and the similar thing happens, context there is also {}.
Could anyone point me to what I might be doing wrong?
UPDATE
ZCML for the form wrapper that calls the form is
<browser:page
name="view"
for="Products.oldproduct.MyFolderishClass"
class=".file.RegionClass"
permission="zope2.View"
/>
Where RegionClass inherits from Form wrapper, could it be permission or traversal issue?
Because your source is a class, you need to instantiate it:
class IStep(interface.Interface):
region = schema.Choice(title=_("Select your country"),
required=True,
source=CountryGenerator(),
default="not_selected")
In certain circumstances, such as with using sub forms or complex form widgets (widget within a widget for list selections, etc), you need to follow the __parent__ pointers to a proper outer context for getting back to the Plone context.

Resources