I have the following spock test. I am first going to the login page, and then I am clicking the login button without entering an email and password to verify the error message. I will add other steps later such as email but no password and email with incorrect password, but I first need to get this test to work.
package loginPageTests
import Pages.loginPage
import geb.Page
import geb.spock.GebReportingSpec
class invalidLoginSpec extends GebReportingSpec {
def "Go to login page"() {
when:
Page loginPage = to loginPage
waitFor { loginPage.loginButton.isDisplayed() }
then:
at loginPage
}
def "Try to log in without email or password"() {
when:
loginPage.loginButton.click()
then:
at loginPage
assert loginPage.loginError.text() == "Please enter your email and password."
}
}
And the following page object
package Pages
import geb.Page
class loginPage extends Page {
static url = 'login/'
static at = { title == "Login to TB"}
static content = {
loginButton {$("#loginButton")}
loginError(wait:true) {$("#loginError")}
}
}
The first method runs successfully, but I get this error when the second method tries to run
groovy.lang.MissingPropertyException: No such property: loginButton
for class: Pages.loginPage
the property loginButton is in the loginPage page object, so I'm not sure why this error is occurring.
The way you are interacting with the page is non-idiomatic but to answer the question asked...
You have defined loginPage as a local variable inside of the first test method and then tried to reference it inside of the second test method where it is out of scope.
Related
I am trying to get my head around groovy scripting to make some changes to a jenkins pipeline and I keep getting this error:
groovy.lang.MissingPropertyException: No such property: credentials for class:
I have tried declaring the variable with def but I still get the exception, eclipse does not recognise that the property exists.
What am I doing wrong?!
#!/usr/bin/groovy
package common.pipeline
import common.pipeline.Credentials
Credentials credentials = new Credentials()
def withCredentials(steps) {
credentials.productionPipeline(steps)
}
This script will be compiled by groovy into a Script class with the field definition inside the run method, and with another method withCredentials that is trying to access the field (kinda like this):
import common.pipeline.Credentials
class Script1 extends Script {
def withCredentials(steps) {
credentials.productionPipeline(steps)
}
def run(args) {
Credentials credentials = new Credentials()
}
}
As you can see, this won't work, as the credentials aren't at Field level in the class...
Groovy has an annotation to make this happen:
#!/usr/bin/groovy
package common.pipeline
import common.pipeline.Credentials
import groovy.transform.Field
#Field Credentials credentials = new Credentials()
def withCredentials(steps) {
credentials.productionPipeline(steps)
}
Below is have a piece of code that handle an alert which contains a drop down:
SoapUI Project Setup Script
import com.eviware.soapui.support.*
def alert = com.eviware.soapui.support.UISupport
def urls = []
project.properties.each
{
if (it.value.name.startsWith("BASE_URL_"))
{
urls.push(it.value.name.replace("BASE_URL_", ""))
}
}
def urlName = alert.prompt("Please select the environment URL", "Enter URL", urls)
What i have noticed is that when I select the x button to close the alert, it still runs the test (which will fail as I have not selected an environment. My question is that how can I write the code so that if the alert is closed (click the x button), it doesn't run the test?
Thank you
Usually, user don't cancel the project execution.
But there is layer that you wrote on top of it before the execution of the project which will actually selects the domain address in the prompt and then cancel as user do not wish to run the project.
Right now, the script you wrote is not doing any condition check. In order to achieve what you are looking for is to have the condition to know if user has clicked on Ok or otherwise do not execute the test suites.
Here is the modified Project level Setup Script:
import static com.eviware.soapui.support.UISupport.prompt
def urls = []
def prefix = 'BASE_URL_'
project.properties.each {
if (it.value.name.startsWith(prefix)) {
urls.push(it.value.name.replace(prefix, ""))
}
}
def suffix = prompt("Please select the environment URL", "Enter URL", urls)
if (suffix) {
log.info 'received user input'
def propertyName = prefix+suffix
def domainAddress = project.getPropertyValue(propertyName)
log.info "Selected environment : ${propertyName} - ${domainAddress}"
} else {
log.warn 'haven\'t received user input'
log.warn 'No base URL is selected or cancelled, try again'
assert false
}
When writing a Groovy script for JIRA Script Runner, how do you get a user, or just their username, given their email address?
It seems that you're supposed to use the findUsersByEmail method in the UserSearchService interface.
https://docs.atlassian.com/jira/7.0.2/com/atlassian/jira/bc/user/search/UserSearchService.html
But how do you get an instance of this class?
Related question: How to get a user by email in a JIRA plugin.
The difference is that question is about a plugin, and my question is about JIRA Script Runner.
This code does not work:
setUserProperties(httpMethod: "POST", groups: ["jira-administrators"])
{ MultivaluedMap queryParams, String body, HttpServletRequest request ->
def userPropertyManager = ComponentAccessor.getUserPropertyManager()
def userManager = ComponentAccessor.getUserManager()
def userSearchService = DefaultUserPickerSearchService;
def users = userSearchService.findUsersByEmail("felicity.smoak#queenconsolidated.com")
users.each {
aUser ->
userPropertyManager.getPropertySet(aUser).setString("jira.meta.Company", "Smoak Technologies")
}
return Response.ok(users).build();
}
This is the error I got:
2016-04-18 15:23:06,168 ERROR [common.UserCustomScriptEndpoint]: *************************************************************************************
2016-04-18 15:23:06,168 ERROR [common.UserCustomScriptEndpoint]: Script endpoint failed on method: POST setUserProperties
groovy.lang.MissingMethodException: No signature of method: static com.atlassian.jira.bc.user.search.DefaultUserPickerSearchService.findUsersByEmail() is applicable for argument types: (java.lang.String) values: [felicity.smoak#queenconsolidated.com]
Possible solutions: findUsersByEmail(java.lang.String), findUserKeysByEmail(java.lang.String)
at Script462$_run_closure3.doCall(Script462.groovy:40)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.doEndpoint(UserCustomScriptEndpoint.groovy:308)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.postUserEndpoint(UserCustomScriptEndpoint.groovy:208)
EDIT
Based on #Oldskultxo's and #BjörnKautler suggestions, this is now my working code:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.user.*
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.sal.api.user.UserManager
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.*
import groovy.transform.BaseScript
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
#BaseScript CustomEndpointDelegate delegate
setUserProperties(httpMethod: "POST", groups: ["jira-administrators"])
{ MultivaluedMap queryParams, String body, HttpServletRequest request ->
def userPropertyManager = ComponentAccessor.getUserPropertyManager()
def userManager = ComponentAccessor.getUserManager()
def userSearchService = ComponentAccessor.getComponent(UserSearchService.class)
def users = userSearchService.findUsersByEmail("felicity.smoak#queenconsolidated.com")
users.each {
aUser ->
userPropertyManager.getPropertySet(aUser).setString("jira.meta.Company", "Smoak Technologies")
}
return Response.ok("200").build();
}
Use ComponentAccessor.getComponent(UserSearchService) to get the right service if there is no concrete getUserSearchService() method.
I usually get components this way:
ComponentManager.getComponentInstanceOfType(UserSearchService.class);
And then just look for its methods.
Regards
On occasion I need to email all Jenkins users, for example warning them Jenkins will be offline for maintenance. The script below gives me email addresses for all people that Jenkins knows about, but it includes people that don’t have accounts, these are people that have committed changes that triggered builds. I’d like to remove them from the email list, that is the list should only include the users that you’d see on the securityRealm page. I’m looking for help modifying the script. Thanks.
import hudson.model.User
import hudson.tasks.Mailer
def users = User.getAll()
for (User u : users) {
def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
print(mailAddress + "; ")
}
First of all you should know that Jenkins will not always be able to tell you whether the user exists or not. From Jenkins' javadoc:
This happens, for example, when the security realm is on top of the servlet implementation, there's no way of even knowing if an user of a given name exists or not.
I found two solutions.
Solution 1
HudsonPrivateSecurityRealm.html#getAllUsers() returns all users who can login to the system. And this works for me:
import hudson.model.User
import hudson.tasks.Mailer
import jenkins.model.Jenkins
def realm = Jenkins.getInstance().getSecurityRealm()
def users = realm.getAllUsers()
for (User u : users) {
def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
print(mailAddress + "; ")
}
Note: this depends on the Jenkins config and may not work on the system where used another (not a HudsonPrivateSecurityRealm) security realm.
Solution 2
SecurityRealm#loadUserByUsername returns user details if user exists and throws UsernameNotFoundException otherwise:
import hudson.model.User
import hudson.tasks.Mailer
import jenkins.model.Jenkins
import org.acegisecurity.userdetails.UsernameNotFoundException
def realm = Jenkins.getInstance().getSecurityRealm()
def users = User.getAll()
for (User u : users) {
try {
realm.loadUserByUsername(u.getId()) // throws UsernameNotFoundException
def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
print(mailAddress + "; ")
} catch (UsernameNotFoundException e) { }
}
This is tricky one, but should work with all security realms as we use the method that exists in top level abstract class (SecurityRealm).
im doing an api for pin payment in pin.net.au and i encounter some errors like what you see in the bottom
`#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder'`,` version='0.5.0-RC2' )
import groovyx.net.http.*
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovy.swing.SwingBuilder
import javax.swing.JFrame
import wslite.http.auth.*
class Customers {
Customers(){
def rst = new RESTClient( 'https://test-api.pin.net.au/1/')
rst.auth.basic 'mySecretKey',''
def res = rst.post( path: 'customers'){
type ContentType.XML
xml {
cards{
email('pk_qTj9Umqmlf3o7lfa6F9nWw')
card[expiry_month]('12')
card[expiry_year]('2015')
card[cvc]('123')
card[name]('patrick pl')
card[address_line1]('23 frfds')
card[address_city]('Angeles')
card[address_postcode]('2009')
card[address_state]('ph')
card[address_country]('Philippines')
}
}
}
}
public static void main(String []args){
new Customers()
}
}
when i run the code the error was
May 12, 2014 1:07:35 PM org.apache.http.impl.client.DefaultRequestDirector handleResponse
WARNING: Authentication error: Unable to respond to any of these challenges: {}
Caught: groovyx.net.http.HttpResponseException: Authorization Required
groovyx.net.http.HttpResponseException: Authorization Required
at groovyx.net.http.RESTClient.defaultFailureHandler(RESTClient.java:240)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:475)
at groovyx.net.http.HTTPBuilder.post(HTTPBuilder.java:335)
at groovyx.net.http.HTTPBuilder$post.call(Unknown Source)
at PinPayment.Customers.<init>(Customers.groovy:16)
at PinPayment.Customers.main(Customers.groovy:39)
how could i make the authentication work for the code to be runable??
here is the link for the docs pin.net.au
Document indicates it requires basic HTTP authn.
Calls to the Pin Payments API must be authenticated using HTTP basic
authentication, with your API key as the username, and a blank string
as the password.
Therefore:
def rst = new RESTClient( 'https://test-api.pin.net.au/1/' )
rst.auth.basic 'secretAPIKeyHereAsString', ''
i found the right code for that particular api here def http = new RESTClient('https://test-api.pin.net.au/1/') http.headers['Authorization'] = 'Basic '+"tWqZl0MHsg5nUQdB6czrDQ:".getBytes('iso-8859-1').encodeBase64()