I'm using Behat/Mink to test a Drupal 8 site.
I have an input field with an IP address and I want to make sure that the IP address has been recorded. I don't want to check for a specific IP address because it might change, so I just want to ensure the field has some value.
Based on the assumption the IP address will include a period, I tried this:
Then the "#edit-field-ip-0-value" element should contain "."
But this fails with the error:
The string "." was not found in the HTML of the element matching css "#edit-field-ip-0-value". (Behat\Mink\Exception\ElementHtmlException)
However, the value of the field is:
172.19.0.1
So there is a period; I don't understand why "contains" doesn't see it.
I also tried checking like this:
Then the "#edit-field-ip-0-value" element should contain "0"
But it fails with the same error (string not found in the HTML of the element).
EDIT
This is the HTML I am trying to target:
<input class="js-text-full text-full form-text" data-drupal-selector="edit-field-ip-0-value" type="text" id="edit-field-ip-0-value" name="field_ip[0][value]" value="172.19.0.1" size="60" maxlength="255" placeholder="">
Here's the code I ended up using:
/**
* #Then the :element element should contain an IP address
*
* Checks that the element with the specified CSS contains IP address value.
*/
public function assertElementContainsIpAddress($element) {
$page = $this->getSession()->getPage();
// Alternately, substitute with getText() for the label.
$element_value = $page->find('css', "$element")->getValue();
$valid_ip_address = filter_var($element_value, FILTER_VALIDATE_IP);
if ($valid_ip_address === FALSE) {
throw new Exception("Valid IP address not found in element $element, which had a value of $element_value.");
}
}
Related
I am trying to capture an URL in a mail paragraph using a Xpath selector (Xpath: html/body/p[2]/text()[3]). I could not get a proper css selector but with Xpath, I'm getting an error as given below when executing the Selenium webdriver test.
<body>
<p>Dear EmailTest user,</p>
<p>
Your profile on the Swwebsite has been successfully created.
<br/>
To begin, click on the link below. You will be prompted to create a password during the login process.
<br/>
https://test.website.com/one/portal/$swweb/?uri=emailuser-125633uu3d-452iekdkd
<br/>
After creating your password, you will be able to access your application with the below username:
<br/>
User Name emailuser_test
<br/>
</p>
Getting the below error:
com.ibm.automation.wtf.driver.DriverException: TypeError: Argument 1 of Window.getComputedStyle does not implement interface Element.
Build info: version: '3.5.2', revision: '10229a9', time: '2017-08-21T17:29:55.15Z'
On some search over internet it seemed a Firefox issue with CSS. Can somebody help me here in fixing the issue or getting a proper CSS selector for capturing URL in the mail
System info: host: 'IBM345-R902EWZ3', ip: '9.162.252.164', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_121'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
First get whole mail body under <p> tag using getText() method, then capturing the URL using Java String operation like split/substring/indexOf method.
Use cssSelector like below:
String mailBody = driver.findElement(By.cssSelector("body > p:nth-child(2)")).getText();
Now parsing the string to capture the URL. For example:
String[] temp = mailBody.split("\n");
String url = temp[2];
System.out.println(url);
Or
int startIndex = mailBody.indexOf("https");
int endIndex = mailBody.indexOf("After creating your password");
String url = mailBody.substring(startIndex, endIndex - 1);
System.out.println(url);
Or you can use any string operation(or regex) to search for the URL from mailBody string
Another try:
You can also get the whole mail body using xpath html/body/p[2] and then parse the string.
Java :
To capture the URL we will first capture the total text under the second <p> tag, then split it once with positive lookaround to include https in the right hand side, then again split it again with positive lookaround to include After in the right hand side and finally print the remaining left hand part. To achieve this you can use the following block of code :
String myText = driver.findElement(By.xpath("//body//following::p[2]")).getAttribute("innerHTML");
String[] textParts = myText.split("(?=https)");
String mySubtext = textParts[1];
String[] subparts = mySubtext.split("(?=After)");
String text = subparts[0];
System.out.println(text);
This prints the following on my console :
https://test.website.com/one/portal/$swweb/?uri=emailuser-125633uu3d-452iekdkd
I have to set the InventLocation Address by code.
By code I know how to find the InventLocation address, but if it isn't there I want to create it.
My code is this :
InventLocation invLocationTable;
LogisticsPostalAddress logisticsPostalAddress;
invLocationTable = InventLocation::find(MYinvLocationId);
logisticsPostalAddress = LogisticsLocationEntity::findPostalAddress(invLocationTable, LogisticsLocationRoleType::None);
if (!logisticsPostalAddress )
{
// Here I want to create/set the InventLocation adress, but I don't know how to do it.
}
Is it possible to create it?
Your InventLocation.RecId will need to be referenced in InventLocationLogisticsLocation.Location, so obviously this table will need to have a record inserted. The next reference will be in InventLocationLogisticsLocationRole.LocationLogisticsLocation, again you will need a record. Finally, the reference in LogisticsPostalAddress.Location.
So first insert into InventLocationLogisticsLocation, then into InventLocationLogisticsLocationRole, finally into LogisticsPostalAddress.
Also make sure that you have a Role Type defined as None, otherwise you might be missing the record in LocationPostalAddress.
In JAVA HttpUrlConnection , the main logic code of request Header settings as following:
public synchronized void set(String k, String v) {
for (int i = nkeys; --i >= 0;)
if (k.equalsIgnoreCase(keys[i])) {
values[i] = v;
return;
}
add(k, v);
}
It is verified that the key should be unique, the key has to keep one to one mapping relationship with the value.
On the contrary, in HeaderFields of Response module, structure is defined as Entry >. That is, the key does not keep one to one mapping relationship with the value.
Why is this? Does the HTTP protocol has relevant agreement?
Add:
In HttpClient4 ,the main logic code of request Header settings as following:
/**
* Replaces the first occurence of the header with the same name. If no header with
* the same name is found the given header is added to the end of the list.
*
* #param header the new header that should replace the first header with the same
* name if present in the list.
*/
public void updateHeader(final Header header) {
if (header == null) {
return;
}
// HTTPCORE-361 : we don't use the for-each syntax, i.e.
// for (Header header : headers)
// as that creates an Iterator that needs to be garbage-collected
for (int i = 0; i < this.headers.size(); i++) {
final Header current = this.headers.get(i);
if (current.getName().equalsIgnoreCase(header.getName())) {
this.headers.set(i, header);
return;
}
}
this.headers.add(header);
}
Header of response
/**
* Gets all of the headers with the given name. The returned array
* maintains the relative order in which the headers were added.
*
* <p>Header name comparison is case insensitive.
*
* #param name the name of the header(s) to get
*
* #return an array of length >= 0
*/
public Header[] getHeaders(final String name) {
final List<Header> headersFound = new ArrayList<Header>();
// HTTPCORE-361 : we don't use the for-each syntax, i.e.
// for (Header header : headers)
// as that creates an Iterator that needs to be garbage-collected
for (int i = 0; i < this.headers.size(); i++) {
final Header header = this.headers.get(i);
if (header.getName().equalsIgnoreCase(name)) {
headersFound.add(header);
}
}
return headersFound.toArray(new Header[headersFound.size()]);
}
They are the same of HttpUrlConnection
Does the HTTP protocol has relevant agreement?
Yes. RFC 2616 Section 4.2 "Message Headers" says:
Multiple message-header fields with the same field-name MAY be
present in a message if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)].
It MUST be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the
interpretation of the combined field value, and thus a proxy MUST NOT
change the order of these field values when a message is forwarded.
This is expanded further by RFC 7230 Section 3.2.2 "Field Order":
A sender MUST NOT generate multiple header fields with the same field
name in a message unless either the entire field value for that
header field is defined as a comma-separated list [i.e., #(values)]
or the header field is a well-known exception (as noted below).
A recipient MAY combine multiple header fields with the same field
name into one "field-name: field-value" pair, without changing the
semantics of the message, by appending each subsequent field value to
the combined field value in order, separated by a comma. The order
in which header fields with the same field name are received is
therefore significant to the interpretation of the combined field
value; a proxy MUST NOT change the order of these field values when
forwarding a message.
i have question about query string in asp.net:
standart query string with query string parameter is "www.mysity.url?key1=value1&key2=value2", but i need only check has query string key or not...yes, one of the correct decisions: www.mysite.url?reset=true, but this excess syntax for me.
in markup i use something like "<a href='UrlHelper.GetResetUrl()'>Reset</a>", this method return "www.mysity.url?reset", but in user side markup i have "Reset"
If you do not specify the name for a parameter it is taken as null.
Its value would be reset
So you would have to check it as follows:
if(Request.QueryString[null]=="reset")
{
//Take some reset action
}
a Quick and dirty solution is:
if(Request.Url.Query.Contains("?reset"))
{
// ok we have a reset
}
Assuming that you have a standard reset call ask as: www.mysity.url?reset and the reset url not have other parameters. If you have you can simple check for the reset keyword.
This code HttpContext.Current.Request["reset"] is always return null, so the next best thing if you like to make it hard, is to manual analyze your keys after the url.
All code that handles querystring parameters should be case insensitive. Browsers (or parts of internet infrastructure?) may convert the case.
One way to check if reset parameter is present in querystring:
bool reset = Request.Url.Query.IndexOf("reset", StringComparison.CurrentCultureIgnoreCase) > -1;
Are there any special considerations trying to read up data from an HTML form where the element is an input type="Password"? When a ColdFusion page POSTs my handler with form data I am getting null for the password instead of the typed value.
Here is the key line from the larger block below:
string password = context.Request.Form["strPassword"];
I have an HTTPHandler.ashx code file that performs an upload of a file when posted. Here is the key snippet of this code:
string username = context.Request.Form["strUsername"];
if (String.IsNullOrEmpty(username))
{
IdentifyInvoker = GetUserInfo();
brokerService = new Broker.FileService();
}
else
{
string password = context.Request.Form["strPassword"];
string domain = context.Request.Form["strDomain"];
IdentifyInvoker = GetInvokerInfoFromForm(username, password, domain);
brokerService = new Broker.FileService(username,password,domain);
}
The form from which the above code is posted (from ColdFusion) looks like this:
<b>User Name</b> <input type="text" name="strUsername" id="strUsername" size="13" />
<b>Password</b> <input type="Password" name="strPassword" id="strPassword" size="15" />
<b>Domain</b> <input type="text" name="strDomain" id="strDomain" size="13" value="cbmiweb" />
I was able to trap this with the debugger and was shocked to see that after this:
string password = context.Request.Form["strPassword"];
... password = null
In the immediate window, sure enough:
?context.Request.Form["strPassword"]
null
If I examine the entire Form collection in the debugger, I see the proper values laid out (separated by &) and none of the important data elements is null (but strangely the data contains a plus sign in front of the equal sign)! Here is a snippet from the immed window:
&strUsername=johna&strPassword+=xxxxxxxx&strDomain+=cbmiweb}
I have an ASP.NET client that POSTs to this same HTTPHandler and that works fine. Here the same form data shows without the interfering PLUS signs:
&strUsername=johna&strPassword=xxxxxxxx&strDomain=cbmiweb}
Any ideas on what causes this and how to retrieve the form data when it's formatted with the intervening PLUS signs?
EDIT:
Both the ASP.NET form and the ColdFusion form specify enctype="multipart/form-data" yet the latter embeds these PLUS signs.
Plus sign is the problem, it should not have been there, is your coldfusion forwarding request to your page or it is using its internal http request engine to do so?
Plus sign appears due to white space, please check in your coldfusion if any string concatenation caused white spaces to be inserted in your posted data?