Test passes but this warning appears: Property 'value' does not exist on type 'HTMLElement' - react-testing-library

I've built a simple react application with a searchbar component. The searchbar component contains an <Input>. For testing I'm using Jest with React Testing Library. I wrote the test below which passes but for some reason this warning appears:
Property 'value' does not exist on type 'HTMLElement'.
It's referring searchInput.value in the code below. How can I deal with this warning?
Searchbar.test.tsx
test("SearchBar value is read", () => {
const handleSearchRequest = jest.fn();
render(<SearchBar searchInputValue="Hello World"/>);
const searchInput = screen.getByPlaceholderText("Search");
expect(searchInput.value).toBe("Hello World");
});

You want HTMLInputElement (and/or HTMLSelectElement and HTMLTextAreaElement).
getByPlaceholderText is not very well named - as it's completely non-obvious what it returns. You should rename it to getInputElementByPlaceholderText and change its return-type to HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement.
As a quick-fix, use as:
test("SearchBar value is read", () => {
const handleSearchRequest = jest.fn();
render(<SearchBar searchInputValue="Hello World"/>);
const searchInput = screen.getByPlaceholderText("Search") as HTMLInputElement | null;
expect(searchInput?.value).toBe("Hello World");
});

Related

How to see the value of a top level empty getter without running the code in Swift?

public var O_RDONLY: Int32 { get }
When I'm looking at stuff inside Darwin.sys.* or Darwin.POSIX.* for example, a lot of these constants are defined as getters. But how does one see the actual value without evaluating the code?
public var O_RDONLY: Int32 { get }
is what the Swift importer generates from the macro definition
#define O_RDONLY 0x0000 /* open for reading only */
in the <sys/fcntl.h> include file. Although this is a fixed value, known at compile time, the Swift importer does not show the value in the generated Swift interface.
Note also that a macro definition in a C header file may depend on other macros, and on other “variables” such as compiler flags, the processor architecture, etc.
I am not aware of a way to navigate to that C definition from a Swift file, or any other way to show the defined value in a pure Swift project. As a workaround, one can
add a C file to the project,
use the macro in some C function, and
“jump to definition” from there.
I ended up with the following solution:
const fs = require('fs');
const { exec } = require("child_process");
const getterRegEx = /^(.*)public var (.+): (.+) { get }(.*)$/;
const code = String(fs.readFileSync('./generatedSwift.swift'));
const lines = code.split('\n').map((line, i) => {
const arr = getterRegEx.exec(line);
if (arr) {
const [all, prefix, constant, type, suffix] = arr;
return `print("let ${constant}: ${type} = ", ${constant}, separator: "")`;
}
return `print("""\n${line}\n""")`;
});
lines.unshift('import Foundation');
fs.writeFileSync('./regeneratedSwift.swift', lines.join('\n'));
exec('swift ./regeneratedSwift.swift', (err, stdout, stderr) => {
if (err) {
console.error(`exec error: ${err}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
Copy definitions generated by the XCode and save into a file named generatedSwift.swift the run node index.js in the same folder.
The output will contain the Swift code where all
public var Constant: Type { get }
are replaced with
let Constant = Value
and all other lines will remain the same.

How to get the state from redux-saga select()?

the saga like below.
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp);
}
the console show
enter image description here
how can i get state like
getState["userLoginReducer","isLogin"] in redux ?
i had tried to code like below.
const tmp = yield select(selectAllState._root.entries);
but error is
index.js:1 TypeError: Cannot read property 'entries' of undefine
It seems you are using Immutable.js for your redux state.
The select effect doesn't convert your Immtuable structure to plain javascript. So you need to use methods of Immutable to get to the values you want. To get the whole Immutable state and then convert it to plain javascript object you can do:
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp.toJS());
}
But generally you will probably want to have selectors to get a subset like the isLogin value. In that case you can do this instead:
function *callUserAuth(action) {
const getIsLogin = (state) => state.get('userLoginReducer').get('isLogin');
const isLogin = yield select(getIsLogin);
console.log(isLogin);
}

AG Grid: Better way for validation row - valueSetter?

Is there a better way to validate a row in ag-grid than with valueSetter?
I can achieve the validation with that but I am not sure, if there is a better way.
https://www.ag-grid.com/javascript-grid-value-setters/#properties-for-setters-and-parsers
I want to validate two fields in the row. DateFrom and DateUntil (they are not allow to be null and DateFrom must be lower than DateUntil).
There are two ways of possible validation handling:
First: via ValueSetter function
and
Second: via custom cellEditor component
I suggest that it would be better to split the logic between custom components, but as you said you need to validate two cell-values between themselves.
On this case from UI perspective you could try to combine them inside one cell and it would be easily to work with values via one component only.
You could override the valueSetter and call the grid api transaction update instead.
Here is pseudo-code that shows how you could implement this.
valueSetter: params => {
validate(params.newValue, onSuccess, onFail);
return false;
};
validate = (newvalue, success, fail) => {
if (isValid(newValue)) {
success();
} else {
fail();
}
};
onSuccess = () => {
// do transaction update to update the cell with the new value
};
onFail = () => {
// update some meta data property that highlights the cell signalling that the value has failed to validate
};
This way you can also do asynchronous validation.
Here is a real example of an async value setter that has success, failure, and while validating handlers that do transaction updates when validation is done.
const asyncValidator = (
newValue,
validateFn,
onWhileValidating,
onSuccess,
_onFail
) => {
onWhileValidating();
setTimeout(function() {
if (validateFn(newValue)) {
onSuccess();
} else {
_onFail();
}
}, 1000);
};
const _onWhileValidating = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: true
};
params.api.applyTransaction({ update: [data] });
};
const _onSuccess = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: false,
lastValidation: true,
value: params.newValue
};
params.api.applyTransaction({ update: [data] });
};
const _onFail = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: false,
lastValidation: params.newValue
};
params.api.applyTransaction({ update: [data] });
};
const asyncValidateValueSetter = validateFn => params => {
asyncValidator(
params.newValue,
validateFn,
_onWhileValidating(params),
_onSuccess(params),
_onFail(params)
);
return false;
};
Here is a code runner example showing this in action: https://stackblitz.com/edit/async-validation-ag-grid-final
Have a look at this two snippets, these come from our internal knowledge base (accessible to customers)
When editing a value in column 'A (Required)', you will see that it does not allow you to leave it empty. If you leave it empty and return the edit, it will be cancelled.
//Force Cell to require a value when finished editing
https://plnkr.co/edit/GFgb4v7P8YCW1PxJwGTx?p=preview
In this example, we are using a Custom Cell Editor that will also validate the values against a 6 character length rule. While editing, if the value is modified outside of 6 characters, it will appear in red, and when you stop editing the row, the value would be reset, so it only accepts a complete edit if the value is valid.
//Inline Validation while editing a cell
https://plnkr.co/edit/dAAU8yLMnR8dm4vNEa9T?p=preview

How to solve TS2349 in a protractor test model

I've got the following test setup, but the transpiler is giving me the following error:
Error:(108, 9) TS2349:Cannot invoke an expression whose type lacks a call signature. Type '((opt_callback?: (value: Model1[]) => R | IThenable, opt_errback?: (error: any...' has no compatible call signatures.
// action class
export class SearchResultsActions {
// setup and other stuff
// Model1 and Model2 are both interfaces
getJSON(): promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>> {
return option.getText().then((selected: string) => {
let searchType: "model1" | "model2" = "model1";
if (selected === "Model 2") {
searchType = "model2";
}
// getResultsEl returns an ElementArrayFinder
return ResultsPage.getResultsEl().map((el, index) => {
let pageObject: Model1PageObject | Model2PageObject = SearchPage.getResult(searchType, index);
let actionObject: Model1Actions | Model2Actions;
if (searchType === "model1") {
actionObject = new Model1Actions(<Model1PageObject> pageObject);
} else {
actionObject = new Model2Actions(<Model2PageObject> pageObject)
}
// both Model1Actions and Model2Actions have a getJSON() method
return actionObject.getJSON(); // returns a JSON object
});
});
}
}
In the search spec where the error is:
SearchResultsActions.getJSON()
.then((res: Array<Model1> | Array<Model2>) => {
// use lodash to perform equality
expect(_.isEqual(res, expected)).toBeTruthy();
});
The curious thing is, despite the error, the transpile works anyway and the tests pass. But I would like to not have the error blaring at me.
I'm using typescript 2.3.3, protractor 5.1.2
Any thoughts? Anywhere I can clarify?
The answer is to change the return type to
promise.Promise<Array<Model1> | Array<Model2>>
which is different from
promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>>
which doesn't work.
Apparently this is true for Observables as well.

Access to the elements of the page in the Page-Worker

I've created a page-worker in the extension
dup = pageWorker.Page({
contentScript: "self.port.on('alert', function(message) {"+
"console.log(message);"+
"document.querySelector('.test-element').title = message;"+
"});",
contentScriptWhen: "ready",
contentURL: "http://example.com/Licznik-beta/addon.html"
});
In "contentScript" I can relate to "document".
But I can not relate to the window, or function, or variable.
console.log(window) in contentScript return "TypeError: cyclic object value timers.js:43".
I do not understand how it works.
Can someone explain to me?
How to change it?
EDIT
I've added a few lines to the test:
self.port.on('addon-licznik', function () {
console.log(document);
console.log(window); // TypeError: cyclic object value timers.js:43
runFromAddon(); // ReferenceError: runFromAddon is not defined timers.js:43
});
Function: runFromAddon(); Of course there is.
Second test:
function funSet (tresc) {
var addonScript = document.querySelector(".addon-script");
if ( addonScript != undefined ) {
document.querySelector('head').removeChild( addonScript );
}
var script = document.createElement("script");
script.className = "addon-script";
script.textContent = tresc;
document.querySelector('head').appendChild(script);
}
function marmo (message) {
console.log(message);
funSet("console.log(window); runFromAddon();");
}
self.port.on('addon-licznik', marmo);
It works well.
Window → http://example.com/Licznik-beta/addon.html
runFromAddon-Log
If you're writing the HTML yourself, then use addon instead of self and attach the script to the page using <script></script> instead of contentScript(File). See Scripting trusted page content.
If you're not writing the HTML, then see Communicating with Page Scripts.