How to test for label of a field from translate service using jasmine - jasmine

I am new to unit testing of angular code using jasmine. I am trying to test the label of a field , which is got from translate service in HTML file.
I have used the below code, but i am getting error "Failed: Cannot read property 'textContent' of null"
it('label should be Enter your mobile number', async(() => {
const de = fixture.debugElement;
expect(fixture.debugElement.nativeElement.querySelector('[id=textFormat] label').textContent).toEqual('ENTER_YOUR_MOBILE_NUMBER');
translate.setTranslation('en', { ENTER_YOUR_MOBILE_NUMBER : 'Enter your mobile number' });
translate.use('en');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('[id=textFormat] label').textContent).toEqual('Enter your mobile number');
}));
HTML :
<div class="form-group" id="email">
<label for="mobileNumber" class="col-form-label col-form-label-lg" id="textFormat">
{{ 'ENTER_YOUR_MOBILE_NUMBER' | translate }} <span class="labelHint" id="numbFormat">(05XXXXXXXX)</span>
</label>
</div>

I think your CSS selector is not accurate, try this:
it('label should be Enter your mobile number', async(() => {
const de = fixture.debugElement;
expect(fixture.debugElement.nativeElement.querySelector('label#textFormat').textContent).toEqual('ENTER_YOUR_MOBILE_NUMBER');
translate.setTranslation('en', { ENTER_YOUR_MOBILE_NUMBER : 'Enter your mobile number' });
translate.use('en');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('label#textForma').textContent).toEqual('Enter your mobile number');
}));
Change what goes in the querySelector.

Related

Firebase Phone Verification in Laravel 9 Inertia.js not working

I want to verify a user's phone number but Firebase phone verification did not send a verification code after successful Recaptcha. Below is my code.
// Import firebase stuff
import {
getAuth,
RecaptchaVerifier,
signInWithPhoneNumber,
} from "firebase/auth";
const auth = getAuth();
auth.languageCode = "en";
onMounted(() => {
render();
});
// Render recaptcha widget
const render = () => {
window.recaptchaVerifier = new RecaptchaVerifier(
"recaptcha-container",
{
size: "normal",
callback: (response) => {
console.log(response);
},
"expired-callback": () => {
console.log("expired-callback");
},
},
auth
);
recaptchaVerifier.render().then((widgetId) => {
window.recaptchaWidgetId = widgetId;
console.log("widgetId", widgetId);
});
};
// Send verification code to a user's phone number
const sendSMSCode = () => {
const appVerifier = window.recaptchaVerifier;
signInWithPhoneNumber(auth, inputPhone.value, appVerifier)
.then((confirmationResult) => {
window.confirmationResult = confirmationResult;
console.log("confirmationResult", confirmationResult);
})
.catch((error) => {
console.log("error", error);
});
};
// HTML code
<CardBox :class="cardClass" is-form #submit.prevent="sendSMSCode">
<FormValidationErrors />
<FormField
label="Phone number"
label-for="phone"
help="Please enter your phone number"
>
<input
type="text"
id="phone"
required
autocomplete="off"
v-model="inputPhone"
/>
</FormField>
<FormField
label="Verification Code"
label-for="code"
help="Please enter a 6-digital code we sent to your phone number"
>
<FormControl
v-model="inputCode"
:icon="mdiAsterisk"
type="text"
id="code"
autocomplete="off"
:min="6"
:max="6"
/>
</FormField>
<div id="recaptcha-container"></div>
<BaseDivider />
<div class="flex items-center justify-between">
<BaseButton type="submit" color="warning" label="Send Code" />
</div>
</CardBox>
After sending the phone number sent,confirmation result did get returned but Recaptcha widget get re-rendered and the OTP code not sent successfully. Why is that? Did I miss something?

Vuejs: invalid expression: Unexpected token ':' in http://example.com

In my project using laravel 7. I'm using vue as frontend framework.
First in my controller I send only one attribute from my query into my template:
$sites = Site::with('users')->where('user_id', Auth::user()->id)->get();
// This is the part
$website_name = '';
if (sizeof($sites) == 0) {
// I fetch website attribute
$website_name = Auth::user()->website;
}
return view('axcess.sites.edit', [
'sites' => $sites,
'website_name' => $website_name // Send it into blade template
]);
In my blade template I send $website_name into component
<div class="row">
<axcess-sites-edit
:websiteName="{{ $website_name }}"
:isNewUser="{{ sizeof($sites) == 0 }}"
></axcess-sites-edit>
</div>
The full vue component is this:
<template>
<div class="col-md-8">
<form>
<div class="form-group">
<input class="form-control" :disabled="isNewUser" v-model="website" />
</div>
</form>
</div>
</template>
<script>
export default {
props: {
websiteName: String,
isNewUser: Boolean
},
data: function() {
return {
website: this.websiteName
}
}
}
</script>
Finally display the page as empty, in my console only display this error:
The problem comes from (:) symbol from http://example.com. There exists a solution for this to display into the input value.

How show server's error in vee-validate with different name?

In my vue/cli 4/vuex / bootstrap-vue project / "vue-router": "^3.1.3" /
"vee-validate": "^3.2.1" / "vue-resource": "^1.5.1",project I use backend rest for saving data and
I have a problem that getting errors from server like
{"message":"The given data was invalid.","errors":{"title":["The title has already been taken."]}}
I can not show it on my form as that is big form with many elements and modal form has more
complicated name , not “title” and I suppose that is why server's error is not shown:
<b-modal id="saveCurrentFilterModal" scrollable size="lg" style="min-width: 720px !important;">
<ValidationObserver
ref="saveCurrentFilterModalForm"
v-slot="{handleSubmit}"
>
<form ref="form" #submit.stop.prevent="handleSubmitOnSaveCurrentFilterOptionsSubmit">
<b-form-group
:state="nameState"
label="Name"
label-for="name-input"
invalid-feedback="Name is required"
>
<ValidationProvider
name="save_current_filter_title" // MORE COMPLICATED TITLE NAMW!
rules="required|max:100"
v-slot="{ errors }"
>
<b-form-input
id="save_current_filter_title"
v-model="save_current_filter_title"
placeholder="Edit saved filter title"
autocomplete="off"
></b-form-input>
<p class="validation_error">{{ clearErrorMessage(errors[0]) }}</p>
</ValidationProvider>
</b-form-group>
<b-button type="submit" size="sm" variant="outline-secondary" class="ml-4">
<i :class="'action_link '+getHeaderIcon('save')"></i>Save
</b-button>
</form>
</ValidationObserver>
handleSubmitOnSaveCurrentFilterOptionsSubmit() {
this.$refs.saveCurrentFilterModalForm.validate().then(success => {
console.log('handleSubmitOnSaveCurrentFilterOptionsSu success::')
console.log(success)
if (!success) {
return;
}
let filters = {
...
}
let self = this
self.$http.post(self.apiUrl + '/personal/ad-saved-filters', filters).then(({data}) => {
console.log(data)
self.showPopupMessage("Saved filter", 'Saved filter was successfully saved !', 'success');
self.$bvModal.hide('saveCurrentFilterModal')
}, error => {
console.error(error)
self.$refs.saveCurrentFilterModalForm.setErrors(error.body.errors); // TO GET ERRORS FROM
self.showPopupMessage("Saved filter", error.body.message, 'warn');
});
});
}, // handleSubmitOnSaveCurrentFilterOptionsSubmit(evt) {
Is there is a way to fix it ?
When you call setErrors you have to have the correct field names specified. So if the server returns title but you need save_current_filter_title, you'll have to have some sort of object that keeps track of the relationship between the server's field names and the client's. For instance, on the client side, you could have this:
let filters = {
...
}
let self = this
self.$http.post(self.apiUrl + '/personal/ad-saved-filters', filters).then(({data}) => {
...
}, error => {
//define this in data, but for example:
var sKey2cKey = {
title: 'save_current_filter_title',
name: 'complicated-client-name',
//etc
}, convertedErrors = {};
Object.keys(error.body.errors).forEach((key) => {
convertedErrors[sKey2cKey[key]] = error.body.errors[key];
});
self.$refs.saveCurrentFilterModalForm.setErrors(convertedErrors);
self.showPopupMessage("Saved filter", error.body.message, 'warn');
});

How to show only one validation at a time in angular 6 form control validators

I am using form control to apply validation in material angular 6 application.
Below is the code of validator :-
paymentOffBankName: new FormControl('', Validators.compose([
Validators.required,
Validators.maxLength(this.responseMap.get('ev_payment_t.bank_name').values.maxSize),
Validators.minLength(this.responseMap.get('ev_payment_t.bank_name').values.minSize),
Validators.pattern(this.responseMap.get('ev_payment_t.bank_name').values.validationExp)
])),
I have one method to display the message related validator :-
paymentOffBankName': [
{ type: 'required', message: 'Required') },
{ type: 'pattern', message: 'Invalid Name' },
{ type: 'minlength', message: 'Requires atleast 3 letters'
},
],
Here is my html which shows the error :-
<mat-form-field fxFlex="{{responseMap.get('ev_payment_t.bank_name').values.maxSize}}">
<input required matInput placeholder="{{responseMap.get('ev_payment_t.bank_name').values.label}}"
formControlName="paymentOffBankName" maxlength="{{responseMap.get('ev_payment_t.bank_name').values.maxSize}}">
<mat-error *ngFor="let validation of validationMessages.paymentOffBankName">
<mat-error class="error-message" *ngIf="offlinePaymentService.OfflinePayment_form.get('paymentOffBankName').hasError(validation.type) && (offlinePaymentService.OfflinePayment_form.get('paymentOffBankName').dirty || offlinePaymentService.OfflinePayment_form.get('paymentOffBankName').touched)">{{validation.message}}</mat-error>
</mat-error>
</mat-form-field>
My Problem is, If I put invalid name with 2 letters, then it shows two validation messages.
Expectation: It should show only one message, I will put one common message like 'Required, MinLengh-3, Alpha Numeric only'
To show only one validation message at a time, try to use messageKey in which you can pass composeMessageKey which contains all the validation messages of the field.
Declare the composeMessageKey in app component
export class AppComponent implements OnInit {
ngOnInit(){
ReactiveFormConfig.set({"validationMessage":{
"composeMessageKey":"please enter valid input"
}});
}
}
and in component ts:
ngOnInit() {
this.userFormGroup = this.formBuilder.group({
paymentOffBankName:['', RxwebValidators.compose(
{validators:[
RxwebValidators.alpha(),
RxwebValidators.maxLength({value:3}),
RxwebValidators.minLength({value:4}),
],messageKey:"composeMessageKey",
})
]
});
}
For that i have used validators of #rxweb validators(RxwebValidators) and passed the MessageKey
Html :
<div>
<form [formGroup]="userFormGroup">
<div class="form-group">
<label>Payment Off BankName</label>
<input type="text" formControlName="paymentOffBankName" class="form-control" />
</div>
<small class="form-text text-danger" *ngIf="userFormGroup.controls.paymentOffBankName.errors">{{userFormGroup.controls.paymentOffBankName.errors.composeMessageKey?.message}}<br/></small>
<button [disabled]="!userFormGroup.valid" class="btn btn-primary">Submit</button>
</form>
</div>
Here is the stackblitz example : Stackblitz

Testing divs exist with Jasmine,Webpack and vue.js

In my vue component I have code that conditionally renders a div:
<div v-if="successCriteria()" id="success">
<div class="row">
<div class="col-md-12">
<Commit-chart :data="chartOptions" ></Commit-chart>
</div>
</div>
</div>
<div v-else>
There has been an error with rendering.
</div>
</div>
and I am trying to test this using jasmine. For example, when the success criteria is met, the success div is present. here is my test:
describe('Graph Tests', () => {
const getComponent = (prop1,prop2) =>{
let vm = new Vue({
template: '<div><graph ref="graph" :label=prop1 :data=prop2></graph></div>',
components: {
graph,
},
})
return vm;
}
it('Renders correctly with valid props', () => {
const label = ['j', 'a' ,'c', 'k'];
const data=[1,2,3,4]
var vm = getComponent(label,data).$mount();
console.info(vm.$refs.graph.$el);
expect(vm.$refs.graph.$el.querySelector('success')).toBeTruthy();
});
});
}
When I log vm.$refs.graph.$el I get:
INFO: <!---->
in the console which I am very confused about. Can anyone help me get the div with id "success" ?
Thank you.
The selector for an id of "success" is '#success'. Or you can use getElementById.
However, the output from your program indicates the component is not rendering at all.

Resources