Uploading file by label tag in capybara - ruby

I have problem uploading file by using capybara and cucumber.
The HTML is the following
<div class="dyn-crm-upload-btn-container">
<label class="btn btn-primary btn-sm" data-bind="visible: newCrmBtnEnabled, enabled: fileEditEnabled">
<i class="fa fa-plus"></i>
<span data-bind="i18n:panels.partnerCrm.new" data-i18n="panels.partnerCrm.new">NEW</span>
<input id="dyn-crm-file-input" class="dyn-crm-upload-btn" type="file" name="file" accept=".csv" data-bind="events: { change: setFileToNewName }"></label>
</div>
And if I have manualy choosed a file, the HTML is following in a new div
<div data-bind="visible: fileUploadVisible" class="dyn-crm-file-upload" style="">
<input type="text" data-bind="value: fileToUpload.name, i18n:[placeholder]panels.partnerCrm.fileUpload.enterName" maxlength="20" class="k-textbox dyn-crm-filename" id="dynCrmFilename" data-value-update="keyup" data-i18n="[placeholder]panels.partnerCrm.fileUpload.enterName" placeholder="File name">
<input type="button" data-bind="click: uploadFileCrmFile,i18n:[value]panels.partnerCrm.fileUpload.upload" value="Upload" class="btn btn-primary" data-i18n="[value]panels.partnerCrm.fileUpload.upload"><div class="file-upload-progress-container">
</div>
I have tried this
attach_file(find('file',:visible=>false),File.absolute_path('C:/Users/user/test.csv'))
And this
attach_file('file',File.absolute_path('C:/Users/user/test.csv'))
And some other variations, but I get the following error
Unable to find file field "file"
Or when using id
Unable to find file field "dyn-crm-file-input"
Also I have tried to execute some scripts before attach_file upload.
I'm using
cucumber 2.1.0
ruby 2.1.6
nokogiri 1.6.6.2
capybara 2.4.4
selenium-webdriver 2.47.1
Thanks in advance :)
EDITED
Here is the link for the css picture:
css picture.

As I imagined, you will have to use jQuery to change the display:none of your element to display:block, for example.
To achieve tis, you can try with this just before attaching the file:
page.execute_script("$('.dyn-crm-upload-btn-container').css('display','block')")

Capybara generally can't call attach_file on a non visible file input. To work around this you need to use #execute_script to modify the file inputs css so it becomes visible on the page and then use attach_file on it.

Related

Playwright + CodeceptJS - Unable to find element by Xpath

In my code I can usually find an element by Xpath and perform actions like shown below
await I.fillField('//*[#id="edit-name"]','user1');
I am seeing the following error when I perform the following action. As the ID is dynamically created. Is there a recommended approach to tackle this type of elements?
await I.fillField('//*[#id="crmUiId_1"]','SomeTextHere');
Error:
**TypeError: Cannot read property '$$' of null
at findElements (node_modules/codeceptjs/lib/helper/Playwright.js:2087:18)
at Playwright._locate (node_modules/codeceptjs/lib/helper/Playwright.js:822:12)**
Associated HTML:
<div crm-ui-field="{name: 'caseTypeDetailForm.title', title: ts('Title')}" class="ng-isolate-scope crm-section"><div class="label">
<label crm-ui-for="caseTypeDetailForm.title" crm-depth="1" crm-ui-force-required="" for="crmUiId_1"><span ng-class="cssClasses"><span ng-transclude=""><span class="ng-binding ng-scope">Title</span></span><span crm-ui-visible="crmIsRequired" class="crm-marker ng-isolate-scope" title="This field is required." style="visibility: inherit;">*</span></span></label>
<!-- ngIf: help -->
</div>
<div class="content" ng-transclude="">
<input crm-ui-id="caseTypeDetailForm.title" type="text" name="title" ng-model="caseType.title" class="big crm-form-text ng-pristine ng-scope ng-empty ng-invalid ng-invalid-required ng-touched" required="" id="crmUiId_1">
</div>
<div class="clear"></div>
</div>
The issue here is actually the ID "crmUiId_1" is dynamically generated. Instead I tried xpath with ng-model="caseType.title" but it doesn't seem to be working either.
I would just make sure you wait for it:
await page.waitForSelector('#crmUiId_1')
await page.fill('#crmUiId_1', 'whatever')
Otherwise the page might still be loading.

Send param in URL using OFBiz

I want to end a param in URL in OFBiz, but I get this error
from security
org.apache.ofbiz.webapp.event.EventHandlerException: Found URL parameter [twCompagneDeRecrutementId]
passed to secure (https) request-map with uri [showCompagne] with an event that calls service [showCompagne];
this is not allowed for security reasons! The data should be encrypted by making it part of the request body (a form field) instead of the request URL.
Moreover it would be kind if you could create a Jira sub-task of https://issues.apache.org/jira/browse/OFBIZ-2330 (check before if a sub-task for this error does not exist). If you are not sure how to create a Jira issue please have a look before at http://cwiki.apache.org/confluence/x/JIB2
This is my ftl
<#if listCompagne??>
<#list listCompagne as newCompagne>
<div style="display:flex; width:100%;">
<div style="padding:6px; width:24%;"><label>${newCompagne.nom}</label></div>
<div style="padding:6px; width:24%;"><label>${newCompagne.dateDebut ?date}</label></div>
<div style="padding:6px; width:24%;"><label>${newCompagne.dateFin ?date}</label></div>
<input type="hidden" value="${newCompagne.twCompagneDeRecrutementId}"/>
<div style="padding:6px; width:20%;"> <a class="btn btn-outline-danger btn-block " href="<#ofbizUrl>showCompagne?twCompagneDeRecrutementId=${newCompagne.twCompagneDeRecrutementId}</#ofbizUrl>">afficher</a>
</div>
</div>
</#list>
I don't use ofbiz , but you should send parameter in body instead of in query.
In your case I would add a form and submit it using hidden form input, form should be unique per iteration using index
<form action="<#ofbizUrl>showCompagne?</#ofbizUrl>" id="afficher${newCompagne?index}" method="post" style="display: none;">
<input type="hidden" name="twCompagneDeRecrutementId" value="${newCompagne.twCompagneDeRecrutementId}" />
</form>
<a class="btn btn-outline-danger btn-block "
href="javascript:;" onclick="javascript:
document.getElementById('afficher${newCompagne?index}').submit()">afficher</a>
the solution is to go to url.properties and change parameters.url.encrypt to no

Select a button on the form of a webpage

I am trying to click on upload button which is inside a <form> tag.
I am using java with selenium. I tried with xpath locator to click on button but unable to identify it.
Html Code:
<form id="sportForm" action="/sportmetadata/saveSport" method="post" enctype="multipart/form-data">
<table>
<tr class="hidden">
<td class="lbl-dialog">Id</font></td>
<td>
<td class="lbl-dialog width200" >Background for Team </td>
<td>
<input type="button" class="btn btn-default btn-command btn-upload" value="Upload" onClick="openFileBrowser('sp_backgroundUploadId')" />
<input id="sp_backgroundUploadId" multiple type="file" class="no-display" name="backgroundUpload" />
<input id="backgroundDelesectUpload" value="Clear" type="button" onclick="clearSelection('sp_backgroundUploadId','sp_backgroundDisplayTableId');" class="btn btn-default btn-command btn-upload" />
</td>
</tr>
Please help
Thanks in advance
Locate Upload button using xpath locator.
//input[#value='Upload'][#type='button']
Explanation:- Use value and type attribute of <input> tag.
Suggestion:- Instead of using absolute xpath, use relative xpath.
OR
Locate Upload button using cssSelector
input[value='Upload'][type='button']
Explanation:- Use value and type attribute of <input> tag.
You should try to avoid XPATH directly copied from browsers as they are not stable ones. When I copy xpath from my browser with the same HTML code I get
//*[#id="sportForm"]/table/tbody/tr/td[4]/input[1] which is different from what you have posted
You should build your xpath more intellegently
This should work
//input[#type='button' and #value='Upload']
You can use cssSelector to identify as follows:
driver.findElement(By.cssSelector("#sportForm > table > tr td:nth-child(3)>input"))

Invisible Recaptcha Badge Positioning Issue

I recently started using Google's new method of Recaptcha - their new Invisible Recaptcha. I realized that the implementation of this version was a little different, as you attach the recaptcha attributes directly to your submit button which then calls google's recaptcha api and begins the verification process. I have all of that working fine, but the one major issue that I am having is with the "Protected by recaptcha" badge positioning.
Upon adding the recaptcha configuration to my submit button, I start seeing the badge on the right of my screen. According to other sites, this badge is supposed to just be a square recaptcha logo until it is hovered and then it is supposed to slide out to be the large rectangle that I am seeing initially on my site.
Here is an image of what I am seeing on my site after implementing the invisible recaptcha.
Here is the submit button code containing the recaptcha attributes:
<button class="btn btn-primary btn-block g-recaptcha" data-sitekey="key"
data-callback="submitsecure" data-badge="bottomright" type="submit">Get Started</button>
Note: The other data-badge options such as inline and bottomleft cause the same positioning issues.
The code of of the form containing the button:
<form action="processjoin.php" method="post" id="signupform" style="padding-top:10px;padding-bottom:10px;max-width:50%;">
<h2 class="sr-only">Login Form</h2>
<div></div>
<div class="illustration"><i class="icon ion-ios-pulse-strong"></i>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<input type="text" name="name" placeholder="Your Name" class="form-control" id="name" />
</div>
<div class="form-group">
<input type="text" name="username" placeholder="Username" class="form-control" id="username" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="email" name="email" placeholder="Email" class="form-control" id="email" />
</div>
<div class="form-group">
<input type="password" name="password" placeholder="Password" class="form-control" id="password" />
</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block g-recaptcha" data-sitekey="6LfdMhkUAAAAAHl-LXZm_gPP1g-UX0aWt8sMR4uW" data-callback="submitsecure" data-badge="bottomright" type="submit">Get Started</button>
</div>
<a href="#" class="forgot">
<div></div>Already have an account? Sign in.</a>
</div>
</form>
I am experiencing two issues with this recaptcha badge:
The badge is glitched outside of its bounding box/border type thing
It also isn't positioned partially off-screen until hovered, like it is supposed to be. I am seeing the full rectangle before I interact with it in any way with my mouse. I should be seeing the square logo until I hover over it, and it slides out to be the full rectangle.
Basically, I need to figure out how to position this properly so that it slides in from off-screen like it is supposed to, and is contained properly inside of its border.
Google Chrome Developer tools tell me that these are the current attributes of the badge div, generated when the window is loaded:
I really appreciate any help that you can provide! If I'm incorrect in thinking that the badge is required, please correct me and I'll force its removal with CSS, however, I'm afraid that this may mess up the captcha verification process and violate Google's policy.
This might help: https://developers.google.com/recaptcha/docs/invisible#config
You can set data-badge="inline" to allow you to control the CSS.
After lots of trial and error, I figured out that the recaptcha badge was positioning to its containing element rather than to the body, and it was also inheriting its line-height from its containing element.
Since I was not directly able to remove the badge from its containing element and move it to the body, I solved the issue with JQuery and a slight CSS change.
JQuery: Appened the badge to the body rather than its containing element (the form)
In order to do this, I had to ensure that the badge had already been fully loaded into the site. Google makes this difficult, but I was able to do it by using jQuery.initialize by timpler.
Once I had the initialize.min.js running on my page, I simply used this code:
jQuery(document).ready(function() {
$('.grecaptcha-badge').appendTo("body"); //fix recaptcha positioning to body
});
$.initialize(".grecaptcha-badge", function() {
$(this).appendTo("body"); //fix recaptcha positioning to body, even if it loads after the page
});
CSS: Added a change to the line-height to position the badge properly with its container
.grecaptcha-badge {
line-height:50px !important;
}
This was a tough one to figure out, but in the end it simply came down to the badge inheriting a few too many attributes from its parent. I hope this helps someone in the future!
You can add captcha in a div element at any place on the page
<div class="g-recaptcha"
data-sitekey="your_site_key"
data-callback="onSubmit"
data-size="invisible">
</div>
When you submit the form the following javascript should be called to start captcha validation
grecaptcha.execute();
The onSubmit function (specified in data-callback tag attribute) will be called on successful captcha validation. There you get the recaptcha token that can be injected as hidden field to your form for backend validation.
function onSubmit(recaptchaToken) {
// inject token as hidden form field and submit form
}

Custom theme for Tumblr: search doesn't work

How can I show search results in my Tumblr theme?
The form:
<form action="/search" method="get">
<input type="text" name="q" value="{SearchQuery}"/>
<input type="submit" value="Search"/>
</form>
The markup:
{block:SearchPage}
????
{/block:SearchPage}
I tried several different variations of this code bot it simply doesn't return any results:
{block:Posts}
{block:SearchPage}
{SearchResultCount}
{Title}
{/block:SearchPage}
....
{/block:Posts}
Try this:
{block:SearchPage}
<div class="result">
<p>{lang:Found SearchResultCount results for SearchQuery 2}</p>
{block:NoSearchResults}<p>{lang:No results for SearchQuery 2}</p>{/block:NoSearchResults}
</div>
{/block:SearchPage}
It must absolutely be outside the Posts block. If you're still having trouble try skimming through a starter theme I've worked on found here. http://git.io/hA6dBA

Resources