Working with checkboxes - unable to check if checkboxes are disabled - testing

Looking for some review on this to let me know if this is the right approach to check for disabled checkboxes.
Part of my page model here:
class eligibleAccountType {
constructor (text) {
this.label = label.withText(text);
this.checkbox = this.label.find('input[type=checkbox]');
}
}
class ProgramOptionsSubscriptionRulesPage{
constructor(){
this.contractsatAccountLevel = Selector("#program_option_allow_participant_account_contracts")
this.eligibleAccountTypesList = [
new eligibleAccountType("Residential"),
new eligibleAccountType("Commercial"),
new eligibleAccountType("Industrial")
];
Part of my test here
if (userdata.userrole == "Read Only") {
for (const eligibleAccountType of programOptionsSubscriptionRulesPage.eligibleAccountTypeList) {
await t.expect(eligibleAccountType.hasAttribute('disabled')).ok()
}
}
Getting error such as:
ReferenceError: label is not defined

I think I found out the problem, I had not defined the
const label = Selector('label');

I see no label definition in your example. You can try to rewrite your eligibleAccountType constructor by using Selector:
class eligibleAccountType {
constructor (text) {
this.label = Selector(...).withText(text);
this.checkbox = Selector(...).find('input[type=checkbox]');
}
}
In this situation it may be useful to check the markup of required elements. Please refer to the "TestCafe Examples" repository: https://github.com/DevExpress/testcafe-examples/blob/master/examples/element-properties/check-element-markup.js
Update:
and now I see that my list is actually not even building and I get this error " 1) TypeError: programOptionsSubscriptionRulesPage.eligibleAccountTypeList is not iterable"
It seems like you have a naming mistake in your loop:
for (const eligibleAccountType of programOptionsSubscriptionRulesPage.eligibleAccountTypeList) {
According to your ProgramOptionsSubscriptionRulesPage class definition, the list name should be eligibleAccountTypesList (with the "s" character).

Related

GraphQL gql Syntax Error: Expected Name, found }

I'm attempting to set up Apollo GraphQL support in a new React project, but when I try to compile a query using gql I keep receiving the error:
Syntax Error: Expected Name, found }
This is generated by the following code:
import gql from 'graphql-tag'
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`
console.log(query)
I'm basing this code off the example code found here: https://github.com/apollographql/graphql-tag
What is the Name referred to in the error message? Does anyone know what I'm doing wrong here?
This error occurs mostly when there are unclosed curly braces or when some fields are not properly defined while calling the query.
The accepted answer didn't solve my issue. Instead, it worked if you remove the initial curly brackets.
The query should look like this instead:
const query=gql`
user(id: 5) {
firstName
lastName
}
`
The causes could be:
you are adding a "()" at the beginning for no reason
you need to add more 'nested' parameters.
Especially if you are using an online GraphiQL editor. Examples:
1- Wrong code (extra parenthesis)
{
allFilms() {
films {
title
}
}
}
2- Wrong code (more parameters need it eg: title)
{
allFilms {
films {
}
}
}
3- Correct code
{
allFilms {
films {
title
}
}
}
GraphQLError: Syntax Error: Expected Name, found "$".
One more example of a similar error (For other users).
theErrorIsHere (Could be extra ( or { before the $varName) added before $speakerId
Error code:
const FEATURED_SPEAKER = gql`
mutation markFeatured($speakerId: ID!, $featured: Boolean!){
markFeatured(speaker_id: theErrorIsHere$speakerId , featured: $featured){
id
featured
}
}
`;
Correct code:
const FEATURED_SPEAKER = gql`
mutation markFeatured($speakerId: ID!, $featured: Boolean!){
markFeatured(speaker_id: $speakerId , featured: $featured){
id
featured
}
}
`;
I'm not 100% sure what the root of my problem was, but moving all the query code into a separate es6 module fixed the issue. There must have been some kind of contamination from the surrounding code. For reference my query was embedded within a React component.
This works:
import gql from 'graphql-tag'
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`
export default query
Another cause for this error: you are referencing a type that is defined further down. Move the type you are referencing up.
For example:
type Launch {
rocket: Rocket
}
type Rocket {
name: String
}
will throw an error, as Launch references Rocket before Rocket is defined.
The corrected code:
type Rocket {
name: String
}
type Launch {
rocket: Rocket
}
In my case, I got the error simply because I'm adding : which I shouldn't have done.
e.g:
const query = `
query($id: String!) {
getUser(id: $id) {
user: {
id
name
email
createdAt
}
}
}
`
If you pay close attention to line 4 of the code above you'll realize that I added : after the user before the curly brace, then I began to list the user's data I wanna query and THAT WAS EXACTLY WHERE THE ERROR WAS!
Removing the : solve the issue!
It should be:
user {
id
name
...
}
In NestJS framework, this error happened to me because I defiled GraphQL field in my schema.graphql file as:
lastUpdated(): Date
Instead it should be just
lastUpdated: Date
(it doesn't take any argument)
I was receiving a similar error server side:
GraphQLError: Syntax Error: Expected Name, found ]
I realized the cause in my case was a type definition with an empty array.
This breaks:
type Settings {
requires: []
}
But this works:
type Settings {
requires: [String]
}
I had this problem and the cause was a string value with double-quotes inside double-quotes, like so: "this "is" bad".
In my case I got the error because of the following:
const GET_POSTS_OF_AUTHOR = gql`
query GetPostsOfAuthor($authorId: Int!) {
postsOf($authorId: Int!) {
id
title
}
}
`;
When it should have been:
const GET_POSTS_OF_AUTHOR = gql`
query GetPostsOfAuthor($authorId: Int!) {
postsOf(authorId: $authorId) {
id
title
}
}
`;
erroneously thought $authorId passed through identically to the function call instead of setting a property inside the function call.
This can happen if you use gql from #clinet/apollo and in the backticks you try to inject dynamic js value. Remove it and replace with normal scalar and it will fix your issue.
example:
${SOME_MAX_VALUE} -> 20
On ny side the error was caused by extra {} Curly braces. Solved by just removing them.
I was getting the same error. In my case putting the id inside double quote solved the issue as the type of id required string value.
{
product(id: "${id}") {
name
}
}
Posting here in case anyone else had this problem but you also get this error if you accidentally make your query look like json with colons (:).
ex:
data {
property {
key: {
deepKey
}
}
}
will give the same error from GQL compile

Aurelia: Update the custom element on changes to the bound object

I have a custom element called summary-bar with summary property:
export class SummaryBarCustomElement {
#bindable summary;
---
In another component test-website, I uses the summary-bar element and bind its data as below:
<summary-bar summary.bind="testWebsiteSummary"></summary-bar>
And here testWebsiteSummary is defined in the test-website.js ViewModel:
export class TestWebsiteCustomElement {
testWebsiteSummary = {
passed_result_count: 0,
failed_result_count: 0,
incomplete_result_count: 0,
unknown_result_count: 0
}
---
There are several functions in TestWebsiteCustomElement class that modify the values of testWebsiteSummary.passed_result_count, testWebsiteSummary.failed_result_count, testWebsiteSummary.incomplete_result_count and testWebsiteSummary.unknown_result_count. However, the summary-bar element is not reloaded with the new values of testWebsiteSummary. Is there a way to achieve that? What I mean is every time the properties of testWebsiteSummary is updated, is it possible to update the summary-bar with the new values? Thank you.
Example of a function which changes the properties:
changeWebsiteSummary(status) {
switch (status) {
case "SUCCESS":
this.testWebsiteSummary.passed_result_count++;
this.testWebsiteSummary.incomplete_result_count--;
break;
case "INCOMPLETE":
this.testWebsiteSummary.incomplete_result_count++;
this.testWebsiteSummary.passed_result_count--;
break;
default:
}
}
When you bind an object into your Custom Element it will update its values automatically. Whenever your TestWebsiteCustomElement changes any of the properties in testWebsiteSummary, those changes will be automatically reflected in your SummaryBarCustomElement. That is, if you are for example displaying testWebsiteSummary.passed_result_count in the SummaryBarCustomElement view, then it will be automatically updated in the ui.
Now, if what you want is to know when those changes occur to do something else, then you need to use a propertyObserver.
Aurelia by default support adding methods such as summaryChanged(newValue, oldValue) to custom elements. This works just fine for primitive values, but for Objects (or arrays) this method will not be triggered if any of the internal properties changes, only if the object itself has been reassigned.
To work around this you can use the binding engine to observe specific properties inside your summary object. Here is what it would look like:
import {bindable, BindingEngine, inject} from 'aurelia-framework';
#inject(BindingEngine)
export class SummaryBarCustomElement {
#bindable summary;
constructor(bindingEngine){
this.bindingEngine = bindingEngine;
}
bind(){
this.subscription = this.bindingEngine.propertyObserver(this.summary, 'passed_result_count')
.subscribe(newValue, oldValue => this.passedResultCountChanged(newValue, oldValue))
}
detached(){
this.subscription.dispose();
}
passedResultCountChanged(newValue, oldValue){
//Do something
}
}
You can use the signal binding behaviour
<summary-bar summary.bind="testWebsiteSummary & signal:'your-signal'"></summary-bar>
And the class:
import {BindingSignaler} from 'aurelia-templating-resources';
export class TestWebsiteCustomElement {
constructor(signaler: BindingSignaler) {
this.signaler = signaler;
}
functionThatChangesValues(){
this.signaler.signal('your-signal');
}
}

Validate Form on Change ONLY

Because much of our imported data technically has validation errors, users are unable to update fields without first correcting previously entered bad data. This wouldn't be a problem except that many times this user doesn't have the information needed to enter a correct value into that field but we still need to save their update.
Is it possible to disable the validate on submit for a DynamicForm?
Is it possible to disable the validate on submit for a DynamicForm?
there's a disableValidation attribute, it disables client-side validators.
The best solution I could find thus far.
I'm disabling validation and overridding getValues, which is called as part of saveData so I manually parse through any fields and look for errors. If I find an error I remove it from the return value and store it under the valuesManager.invalidatedFields.
If a field had an error it will not be included in the save, but because the server will return the original value I had to override setValues as well to prevent your (bad) change from being overridden.
Also, because getValues is called on initial load it validates on load as well.
isc.ValuesManager.create({
disableValidation: true,
invalidatedFields: {},
setValues: function(values){
console.log("setting values..", this.invalidatedFields);
for (var key in this.invalidatedFields) {
if (this.invalidatedFields.hasOwnProperty(key)) {
values[key] = this.invalidatedFields[key];
}
}
this.Super("setValues", arguments);
},
getValues: function () {
this.invalidatedFields = [];
var data = this.Super("getValues");
for (var key in data) {
if (data.hasOwnProperty(key)) {
var form = this.getMemberForField(key);
if (form && !form.getField(key).validate()) {
console.log(key + " failed validation", data[key]);
this.invalidatedFields[key] = data[key];
delete data[key];
}
}
}
return data;
}
});

Aurelia validation errors not displayed when validation initialized on attached

I want to show invalid input fields when the view is shown.
I have validation rules setup in a separate class (UserValidation) with one function (initValidatorOn).
export class UserValidation {
public _validation: Validation;
constructor(validation: Validation) {
this._validation = validation;
}
initValidatorOn(user: UserDto): ValidationGroup {
return this._validation.on(user, null)
.ensure('name').isNotEmpty();
}
}
Everything works for this setup.
export class User {
public validationGroup : ValidationGroup;
public userValidation : UserValidation;
public user : UserDto;
constructor(uv: UserValidation) {
this.userValidation = uv;
//this code works here and in activate method
this.validationGroup = this.userValidation.initValidatorOn(this.user);
}
attached() {
this.validationGroup.validate();
}
}
As I said before, the above works. But sometimes the object that I need to validate I not available in constructor or in activate function so I need to initialize validation in attached function. When I do that, my view no longer shows validation errors until I update the value in input.
So, this doesn't work
attached() {
this.validationGroup = this.userValidation.initValidatorOn(this.user);
//no validation errors displayed on the view
this.validationGroup.validate();
}
Can someone explain why errors aren't displayed on the view after I call validate when I initialize validationGroup in attached function?
Thank you.

How to skip value in config if it doesn't exist?

I am writing App, that need to read config at start. Some is not necessary for work.
class ParseConfig
{
string optionalkey;
//...
this()
{
this.optionalkey = config.getKey("key1");
}
//...
}
The problem that I need to find way to skip (do not try to find and parse) it if not exists and config. Now App try to parse config and show me error.
I found only one way - to wrap all in try-catch block, and if value can't be found in config in cantch block set it's to null.
What is the best way to do it?
I am using dini for config.
upd: (added example)
import std.stdio;
import std.path;
import std.file;
import dini;
void main()
{
string confpath = buildPath(getcwd, "config.ini");
if (!exists(confpath)) throw new Exception("ERROR: config.ini do not exists");
auto config = Ini.Parse(confpath);
try
{
string optionalkey;
if(config.getKey("optionalkey"))
{
optionalkey = config.getKey("optionalkey");
}
writeln(optionalkey); // nothing will shown, becouse exception
}
catch( Exception e)
{
writeln("Exception! :(");
writeln(e.msg);
}
}
Catching exception is one way, but it is not perfect (mainly if there will be many cases of optional configs). So better way is test if key exist:
class ParseConfig
{
string optionalkey;
//...
this()
{
this.optionalkey = config.hasKey("key1") ? config.getKey("key1") : "defaultValue";
}
//...
}
But ideal would be if dini has overload of getKey method so you can use something like this:
this.optionalkey = config.getKey("key1", "defaultValue");
But from sources I see it does not have it, but I plan to add it and make a PR.
UPDATE
PR: https://github.com/robik/DIni/pull/3
Wrote a pretty advanced ini file wrapper today which supports sections, comments, thread-safety, default values for reading, writing/reading using template values, entry checks etc.
You can get it here:
https://github.com/BaussProjects/baussini
Here is an example usage (example.d from the repo)
module main;
import baussini;
import std.stdio : writefln, readln;
void main() {
string fileName = "test.ini";
// Thread-safe instance, for a non thread-safe instance replace "true" with "false"
auto ini = new IniFile!(true)(fileName);
// Use open() for reading and close() for write. Both can be combined ...
if (!ini.exists()) {
ini.addSection("Root");
// Write way 1
ini.write!string("Root", "StringValue1", "Hello World!");
// Write way 2
ini.getSection("Root").write!int("IntValue1", 9001);
// Write way 3
ini.getSection("Root")
.write!string("StringValue2", "Hello Universe!")
.write!int("IntValue2", 1000000);
ini.close();
}
else {
ini.open();
// Read way 1
string stringValue1 = ini.read!string("Root", "StringValue1");
// Read way 2
int intValue1 = ini.getSection("Root").read!int("IntValue1");
// Read way 3
string stringValue2;
int intValue2;
ini.getSection("Root")
.read!string("StringValue2", stringValue2)
.read!int("IntValue2", intValue2);
writefln("%s is %s", "stringValue1", stringValue1);
writefln("%s is %s", "intValue1", intValue1);
writefln("%s is %s", "stringValue2", stringValue2);
writefln("%s is %s", "intValue2", intValue2);
readln();
}
}
In your case you could either use IniFile.hasKey or IniSection().hasKey()
Example:
// Check way 1
if (ini.hasKey("Root", "StringValue1")) {
// The section "Root" has an entry named "StringValue1"
}
// Check way 2
auto section = ini.getSection("Root");
if (section.hasKey("StringValue1")) {
// The section "Root" has an entry named "StringValue1"
}
You could also use default values.
string stringValue1 = ini.getSection("Root").read!string("StringValue1", "Default");
// stringValue1 will be "Default" if it doesn't exist within "Root"
The default value has to be a string input, but it will always convert the value of it to T.
Ex.
int defaultValue = ini.getSection("Root").read!int("IntValue3", "1000");
// defaultValue will be 1000 if it doesn't exist within "Root"
You can test if a key is present with hasKey
class ParseConfig
{
string optionalkey;
//...
this()
{
if (config.hasKey("key1"))
this.optionalkey = config.getKey("key1");
}
//...
}
assuming that we talk about the same dini