GEB find first visible element - testing

I have got some hidden buttons on the page. When I click on text input, one of these buttons shows on the page. Before:
<div field='login'>
<input type="text">
<button class="submit" style="display: none">Save</button>
</div>
<div field='name'>
<input type="text">
<button class="submit" style="display: none">Save</button>
</div>
After click on second input:
<div field='login'>
<input type="text">
<button class="submit" style="display: none">Save</button>
</div>
<div field='name'>
<input type="text">
<button class="submit">Save</button>
</div>
So I try to interact with second button by next selectors in my test:
static content = {
submitButton { $("button.submit") }
}
but I have next error:
isorg.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
If I write:
static content = {
submitButton { $("button.submit", 1) }
}
it works, but I need to work with one first visible button on the page. What is wrong?

Unfortunately there is no css selector to find visible elements but you can use displayed property of Navigator and its findAll() method to find the button that is visible:
static content = {
submitButton { $("button.submit").findAll { it.displayed } }
}

Related

Vue click two input one button

I want to pick a new value when the button is clicked, but I can't
<div class="col-lg-12 col-sm-6 col-4" style="margin-top:5px;">
<p style="margin-bottom:0rem;" > Цена</p>
<label>
<input id="PriceRangeMin" type="number" :value='text' >
-
<input id="PriceRangeMax" placeholder="до" type="number" :value='text1'>
</label>
<button id="PriceRangeMin" type="submit" style="margin-left:30px;" #click='textcon()'>Применить</button>
</div>
My script
<script>
export default {
name: 'Applesmartphone',
data () {
return {
text:[],
text1:[]
}
},
methods: {
textcon(){
console.log(text)
console.log(text1)
}
}
}
Hi, I want to pick a new value when the button is clicked, but I can't.
Bind input to properties using v-model like :
input id="PriceRangeMin" type="number" v-model='text' >
then use this to access that properties inside the method :
textcon(){
console.log(this.text)
console.log(this.text1)
}

boostrap vue modal not hide when click ok button with validation

I want to add validation to a modal window, I need a behavior in which when the OK button (form submission) is clicked, validation would take place, and if the result is negative, the window should not close
my modal
<b-modal
size="lg"
id="modalToRepair"
title="Add Problem"
title-class="font-18"
centered
body-class="p-4"
no-close-on-backdrop
no-close-on-esc
#ok="onClickModalRepair"
>
<div class="row">
<div class="col-lg-12">
<div class="form-group row">
<label class="col-4 col-form-label">
Repair Problem
<span class="text-danger">*</span>
</label>
<div class="col-8">
<input
v-model="theProblem"
type="text"
class="form-control"
placeholder="Input problem"
name="theProblem"
:class="{
'is-invalid': typesubmit && $v.theProblem.$error
}"
/>
<div
v-if="typesubmit && $v.theProblem.$error"
class="invalid-feedback"
>
<span v-if="!$v.theProblem.required">Requred field.</span>
</div>
</div>
</div>
</div>
</div>
</b-modal>
and my methods
Vue.js
methods: {
onClickModalRepair() {
this.typesubmit = true;
this.$v.$touch();
if (this.$v.$invalid) {
this.$bvModal.show("modalToRepair"); // not work - modal hide
//code for not hide this modal
return;
}
}
},
validations: {
theProblem: {
required
}
}
is it possible?
The method used in the #ok event, is passed an event, which you can call .preventDefault() on, if you want to prevent the modal from closing.
onClickModalRepair(bvModalEvt) {
this.typesubmit = true;
this.$v.$touch();
if (this.$v.$invalid) {
bvModalEvt.preventDefault();
return;
}
}
You can see an example of this on the docs.

How to pass a dynamicy changed model to Partial view?

I have a list of "workbooks" displayed in a table. Each workbook has a "Share" button next to the workbook's title. When the user clicks on the share button a modal dialog is shown containing a form.
The form allows the user to enter a list of the recipient's emails separated by a comma which is validated on the client-side.
As the dialog is located in a partial view _ShareView.cshtml that allows me to pass a modal WorkbookShareModel that has some fields like WorkbookId and Title. The goal here is to pass the details of each workbook when the user presses the share button (i.e. construct a modal and pass it to the already rendered model).
I am not sure how to pass a model to an already rendered view?
The solution have to be done on the client (i.e. dont involve actions on the server that return the partial view provided the parameters are passed). I want to avoid unnesessary calls to the server - we have all the data on the client regarding a workbook and I need to do a POST when the user types in list of emails.
This is my index.cshtml:
#section BodyFill
{
<div id="shareFormContainer">
#{ await Html.RenderPartialAsync("_ShareView", new WorkbookShareModel());}
</div>
<div class="landing-container">
<div class="workbook-container">
<table class="table">
<tbody>
#foreach (var workbook in Model.Workbooks)
{
string trClassName, linkText;
if (workbook.Metadata.SharedBy == null)
{
trClassName = "saved-workbooks";
linkText = workbook.Name;
} else {
trClassName = "shared-with-me";
linkText = string.Format(
BaseLanguage.SharedWithMeWorkbook,
workbook.Name,
workbook.Metadata.SharedBy,
workbook.Metadata.SharedDate.ToShortDateString()
);
}
<tr class="#trClassName">
<td>#Html.ActionLink(linkText, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td class="last-modified-date" title="Last Modified Date">#workbook.ModifiedDate.ToShortDateString()</td>
<td class="share">
<button title="Share" class="share-button" onclick='showSharingView("#workbook.Name", "#workbook.Id", "#Model.Id")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
}
#section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
#await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
// hide the modal as soon as the page loads
$('#shareFormModal').modal("hide");
function showSharingView(title, workbookId, id) {
$('#shareFormModal').modal("show");
// how to pass a WorkbookShareModel to my partial view from here?
}
function hideDialog() {
var form = $("#partialform");
// only hide the dialog if the form is valid
if (form.valid()) {
activateShareButtons();
$('#shareFormModal').modal("hide");
}
}
// Helper method that validates list of emails
function IsEmailValid(emailList, element, parameters) {
var SPLIT_REGEXP = /[,;\s]\s*/;
var EMAIL_REGEXP =
/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+##[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/i;
var emails = emailList.split(SPLIT_REGEXP);
for (var i = emails.length; i--;) {
if (!EMAIL_REGEXP.test(emails[i].trim())) {
return false;
}
}
return true;
}
</script>
}
That is my dialog:
#using DNAAnalysisCore.Resources
#model DNAAnalysisCore.Models.WorkbookShareModel
#* Partial view that contains the 'Share Workbook dialog' modal *#
<!-- Modal -->
<div onclick="activateShareButtons()" class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - #Model.Title</h4>
</div>
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new { #id = "partialform" }))
{
<div class="modal-body">
<label>#BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="#BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title" />
<input asp-for="Id" />
<input asp-for="WorkbookId"/>
</div>
<div class="modal-footer">
<button onclick="hideDialog()" type="submit" class="btn btn-primary">Share</button>
<button onclick="activateShareButtons()" id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
There are two solutions to solve your problem :
Option 1 :
Since you have got the parameters(title, workbookId, id) , you can call server side function using AJAX to render the partial view , then replace the DIV contained in the partial view with the updated contents in the callback function of AJAX .
You can click here for code sample .
Option 2 :
Directly update related input/area using Jquery . For example , the input tag helper :
<input asp-for="<Expression Name>">
generates the id and name HTML attributes for the expression name specified in the asp-for attribute. So you can set the value using Jquery like :
$("#Title").val("Title")
Please click here for Tag Helpers in forms in ASP.NET Core
With Option 2 , you need to clear the Emails area firstly after user click the share button ; With Option 1 , you don't need to care that since the HTML will replace entirely .

Angular 5 template-driven form for creating and editing close issue (ng-bootstrap modal)

I have such Angular 5 template-driven form made with ng-bootstrap modal
<button type="button" class="close" (click)="activeModal.close()"
aria-label="Close">
<span aria-hidden="true">x</span>
</button>
<form (ngSubmit)="editMode ? editBoard(board) : addBoard(newBoard.value)"
#newBoard="ngForm"
id="newBoard"
name="newBoard"
novalidate>
<div class="form-group">
<label>Board name</label>
<input type="text"
*ngIf="editMode"
class="form-control"
name="name"
#name="ngModel"
[ngModel]="board?.name"
(input)="changeName(board, name.value)"
placeholder="Enter a board name (required)"
autofocus
required>
<div *ngIf="name.touched && name.errors">
<div *ngIf="name.errors.required" class="alert alert-danger">Board name is required</div>
</div>
</div>
</form>
I want to use it for create and for edit. While adding and editing it's Ok but when I'm closing empty form modal (open and close) with "Close" or "x" buttons I have an error when input into field:
ERROR TypeError: Cannot set property 'name' of undefined
Here is a function to open a modal
public openBoardModalToAdd(): void {
const ref = this.modal.open(BoardModalComponent,
{
keyboard: false,
backdrop: 'static',
size: 'lg'
}
);
ref.componentInstance.board = {name: ''};
ref.result.then(board => this.boards = [...this.boards, board]);
}
How I can fix this?

Unable to Disbale the DOJO dijit.form.Form

I have a Form and i want to disable the entire form on click of a Button ,please see this code
<div dojoType="dijit.form.Form" id="myForm" jsId="myForm" encType="multipart/form-data"
action="" method="">
<table>
<input type="text" id="name" name="name" required="true" dojoType="dijit.form.ValidationTextBox"
<input type="text" id="dob" name="dob" dojoType="dijit.form.DateTextBox"
</table>
<button dojoType="dijit.form.Button" type=button onClick="console.log(myForm.getValues())">
Get Values from form!
</button>
<button dojoType="dijit.form.Button" type="submit" name="submitButton"
value="Submit">
Submit
</button>
<button dojoType="dijit.form.Button" type="reset">
Reset
</button>
<button dojoType="dijit.form.Button" onClick="callMe()">
Disable IT
</button>
</div>
I have written a function callMe to disable this
function callMe()
{
dijit.byId('myForm').disabled=true;
}
Dijit forms do not have a property "disabled", but rather you have to overwrite the onSubmit event:
dijit.byId('myForm').onSubmit = function () {
// If we return false here, the form will not be submitted.
return myMagicEnabledFlag;
};
Note that you cannot use dojo.connect as you have to modify the return value of the event and not just connect to it.
For disabling the entire form elements, use the "getChildren()" function of the dijit form, which would return the array of all the field widgets of that corresponding form. Then, you need to disable the widgets of that array. See below sample:-
dijit.byId('myForm').onSubmit = function () {
var widgets = dijit.byId('myForm').getChildren();
for(var i=0;i<widgets.length;i++) {
widgets[i].set('disabled', true);
}
//if you need to prevent the form submission & just disable, return false,
//else ignore the following return stmt
return false;
};