How to reset state beforeEach/afterEach jest test? - jestjs

My components all needed to be wrapped by a state provider in order for them to work, so when I render each component for testing I wrap them in the state provider. Like so:
<StateProvider>
<ThemeProvider theme={theme}>
<Component_Being_Tested />
</ThemeProvider>
</StateProvider>
The issue I have is that when a component changes state during its test, it doesn't reset the state back to its initial state before the next test runs. This causes many tests to fail.
For example, I have a password input component that includes a 'show/hide password' button. When clicked, it toggles a boolean state value showPassword. The initial state is set to false, which results in the input type being 'password'. On the first click, it changes the state to true and the component changes the input type to 'text'.
When I run a test on this component that involves clicking the button, the first test runs just fine. However after this first test is run, the state for showPassword remains as true instead of resetting back to its initial false value.
Therefore if I run another test that involves clicking the button, the test will fail as clicking the button will toggle the showPassword state back to its initial false whereas the test is expecting it to change to true.
I've tried creating a function that resets state and running it in beforeEach(), like so:
beforeEach(() => useContext(Store).dispatch(resetState()));
However it fails as useContext is a React Hook and can only be called within a function component.
How else can I reset state before/after each test?

If you would use React Testing Library you could use afterEach(cleanup).
Besides that, I would change your component architecture. Split it into display and container components. That way you can explicitly test the display (presentational) component by controlling its state in the test. And you can test the container components using functional and/or E2E tests. Here is a great guide for testing React.

Related

Test quickly changing scenario using selenium web driver in nodejs

I have a button which triggers a rest call and upon click of that button until the rest call triggers I disable the button.
I am writing a test case using selenium web driver and nodejs
button = driver.findElement(By.class("btn"));
await button.click();
console.log(await button.isEnabled()) //outputs true
But I can see that the button is being disabled and I am sure Iam selectingthe correct button the findElement statement.
The documentation for .isEnabled() says:
Is the element currently enabled or not? This will generally return true for everything but disabled input elements.
So what you are seeing is expected behaviour.
To test your scenario, you will need the following approach:
click your button
click the same button again
the second click you are expecting to fail, so you will have to wrap it in whatever is the node.js equivalent of try..catch (sorry, I'm a Java guy)
inside of the catch, set a variable to true
afterwards test the variable has been set
The scenario you have described is to click a button, verify it becomes disabled, and then verify it becomes enabled. There are probably a few ways to do this. I'm looking at the documentation and here is one way:
button = driver.findElement(By.class("btn"));
button.click();
driver.wait(until.elementIsDisabled(button));
driver.wait(until.elementIsEnabled(button));
If the button never becomes disabled, an exception will be thrown. If the button never becomes reenabled, an exception will be thrown. So, the fail condition is either one throwing an exception. The pass condition is no exceptions.
NOTE: disabled and enabled, in Selenium terms, is generally referring to an INPUT tag. If your button is not an INPUT tag, then this won't work. You will need to detect some CSS style being applied/removed to determine disabled/enabled.

How to enable/disable the features depending to result of some method on adf mobile

Firstly, I want to start a taskflow automatically when just application runs. Then, i m checking something and assigned result to a variable(i think that its scope must be applicationLevel)
And now, as i tried to describe on title, i want to manipulate application features(actually i mean that just disable/enable) up to that variable, such on this link: http://adf4beginners.blogspot.com/2013/02/adf-mobile-playing-around-with-features.html?showComment=1387060885861#c1358489250811721156
Is it possible? How can i achieve this?
in order to start a task flow when application run, you need to create a feature and go to the content tab under the created feature then create the ADF Task flow from inside the feature.
It will be automatically added to
Application Resources->Descriptors->ADF META-INF->adfmf-application.xml->Feature References
if you could see your feature there then it will start automatically when the app run.
About your second question yes it's possible:
1- create a Java class as managed bean and add it to your feature (or application if it's application scope)
2- create a variable in that class String rendered = "false";
3- right click generate accessors (make sure that notify listener check box is selected)
4- go to your component properties -> Rendered -> click on the arrow beside the textbox
5- Select your variable under the bean created under the scope of the bean.
6- run the application the component should be hidden.
7- if you changed your variable value to "true" the component will be visible again.

jqueryValidation Engine inline ajax validation stopping form submit

I'm trying to validate a multipart form using the jquery validateEngine plug in.
I can validate the form correctly for all fields however I want to take it one step further and use the built in ajax validation.
I want to check whether a name is unique compared to a database. This function works correctly and I get the expected results however I am unable to submit the form and by running validation in firebug console on the form it validates as false even though all fields are correct.
If I remove the ajax validation the form validates correctly so somewhere in this script a false flag is being set but I just don't know where to look or over ride it
The validation is initialised by:
if ($.validationEngine) {
form.validationEngine();
}
and as I say normal validation works.
I've set up the class in my form as:
class="input validate[required, ajax[ajaxNameCallPhp]]"
The script in the validation engine relating to this method has been changed to this:
"ajaxNameCallPhp": {
// remote json service location
"url": "http://localhost/greenFees/includes/lib/greenFee/checkName.php",
// error
"alertText": "* This name is already taken",
"alertTextOk": "* This name is available",
"alertTextLoad": "* Validating, please wait"
},
Any help appreciated with this issue
Ok - managed to get this to work after a few hours logging the script in firebug...
Anyway. The culprit of sorts is partly do do with another script - form wizard which turns a form into a wizard, it adds a next button which on click runs the validation. For some reason the validation when called from there behaves differently to the form submit.
With the ajax validation it displays a flag if the nameis ok, if it's already used or a notice when validating.
Solution 1:
Remove the wizard script but then the form doesnt behave correctly
Solution 2: remove the notice alertTextLoad - it appears the validation is treating the presence of this flag as an error rather than info - removing it meant I can keep the wizard
Ta

XPages sometimes refresh and lose content

I hope someone can help me solve a very serious problem we face at the moment with a business critical application losing data when a user works in it.
This happens randomly - I have never reproduced this but the users are in the system a lot more than me.
A document is created with a load of fields on it, and there are 2 rich text fields. We're using Domino 8.5.3 - there are no extension lib controls in use. The document has workflow built in, and all validation is done by a SSJS function called from the data query save event. There is an insane amount of logging to the sessionscope.log and also this is (now) captured for each user in a notes document so I can review what they are doing.
Sometimes, a user gets to a workflow step where they have to fill in a Rich Text field and make a choice in a dropdown field, then they submit the document with a workflow button. When the workflow button is pressed (does a Full Update) some client side JS runs first
// Process any autogenerated submit listeners
if( XSP._processListeners ){ // Not sure if this is valid in all versions of XPages
XSP._processListeners( XSP.querySubmitListeners, document.forms[0].id );
}
(I added this to try and prevent the RTF fields losing their values after reading a blog but so far it's not working)
then the Server-side event runs and calls view.save() to trigger QS code (for validation) and PS code to run the workflow agent on the server.
95% of the time, this works fine.
5% of the time however, the page refreshes all the changes made, both to the RFT field (CKEditor) and the dropdown field are reloaded as they were previously, with no content. It's like the save hasn't happened, and the Full Update button has decided to work like a page refresh instead of a submit.
Under normal circumstances, the log shows that when a workflow button is pressed, the QuerySave code starts and returns True. Then the ID of the workflow button pressed is logged (so I can see which ones are being used when I am reviewing problems), then the PostSave code starts and finally returns true.
When there is a problem, The QuerySave event runs, returns true if the validation has passed, or false if it's failed, and then it stops. The ID of the workflow button is also logged. But the code should continue by calling the PostSave function if the QuerySave returns true - it doesn't even log that it's starting the PostSave function.
And to make matters worse, after the failure to call the PostSave code, the next thing that is logged is the beforePageLoad event running and this apparently reloads the page, which hasn't got the recent edits on it, and so the users loses all the information they have typed!
This has to be the most annoying problem I've ever encountered with XPages as I can find no reason why a successful QuerySave (or even a failure because mandatory fields weren't filled in) would cause the page to refresh like this and lose the content. Please please can someone help point me in the right direction??
It sounds as if in the 5% use cases, the document open for > 30mins and the XSP session is timing out - the submit causes the component tree to be re-created, and the now empty page returned back to the user. Try increasing the time out for the application to see if the issue goes away.
I would design the flow slightly different. In JSF/XPages validation belongs into validators, not into a QuerySave event. Also I'd rather use a submit for the buttons, so you don't need to trigger a view.save() in code. This does not interfere with JSF's sequence of things - but that's style not necessarily source of your problem.... idea about that:
As Jeremy I would as a first stop suspect a timeout, then the next stop is a fatal issue in your QuerySave event, that derails the runtime (for whatever reason). You can try something like this:
var qsResult = false;
// your code goes here, no return statements
// please and if you are happy
qsResult = true;
return qsResult;
The pessimistic approach would eventually tell you if something is wrong. Also: if there is an abort and your querySave just returns, then you might run in this trap
function noReturn() {return; } //nothing comes back!
noReturn() == true; --> false
noReturn() == false; --> false
noReturn() != false; --> true!!!!
What you need to check: what is your performance setting: serialize to disk, keep in memory or keep latest in memory? It could be you running foul of the way JavaScript libraries work.
A SSJS library is loaded whenever it is needed. Variables inside are initialized. A library is unloaded when memory conditions require it and all related variables are discarded. so if you rely on any variable in a JS Function that sits inside a SSJS library between calls you might or might not get the value back, which could describe your error condition. Stuff you want to keep should go into a scope (viewScope seems right here).
To make it a little more trickier:
When you use closures and first class functions these functions have access to the variables from the parent function, unless the library had been unloaded. Also functions (you could park them in a scope too) don't serialize (open flaw) so you need to be careful when putting them into a scope.
If your stuff is really complex you might be better off with a backing bean.
Did that help?
To create a managed bean (or more) check Per's article. Your validator would sit in a application bean:
<faces-config>
<managed-bean>
<managed-bean-name>workflowvalidator</managed-bean-name>
<managed-bean-class>com.company.WfValidator</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
</faces-config>
Inside you would use a map for the error messages
public Map<String,String> getErrorMessages() {
if (this.errorStrings == null) { // errorStrings implements the MAP interface
this.loadErrorDefinitions(); //Private method, loads from Domino
}
return this.errorStrings;
}
then you can use EL in the Error message string of your validators:
workflowvalidator.errorMessage("some-id");
this allows XPages to pick the right one directly in EL, which is faster than SSJS. You could then go and implement your own custom Java validator that talks to that bean (this would allow you bypass SSJS here). Other than the example I wouldn't put the notes code in it, but talk to your WfValidator class. To do that you need to get a handle to it in Java:
private WfValidator getValidatorBean() {
FacesContext fc = FacesContext.getCurrentInstance();
return (WfValidator) fc.getApplication()
.getVariableResolver()
.resolveVariable(fc, "workflowvalidator");
}
Using the resolver you get access to the loaded bean. Hope that helps!
My experience is that this problem is due to keeping page in memory. Sometimes for some reason the page gets wiped out of memory. I'm seeing this when there is a lot of partial refreshes with rather complex backend Java processing. This processing somehow seems to take the space from memory that is used by the XPage.
The problem might have been fixed in later releases but I'm seeing it at least in 8.5.2.
In your case I would figure out some other workaround for the CKEditor bug and use "Keep pages on disk" option. Or if you can upgrade to 9.0.1 it might fix both problems.

Why doesn't IN transition work for the first opened Form?

In the startApp() of the MIDLet I show a Form ( the main Form of the application ) . The problem is that even if I set setTransitionInAnimator then the Transition is not effect at runtime ! So how to make transition for the first opened Form from the MIDLet ?
Transitions apply between 2 components/forms hence the first form will never have a transition since there is nothing to transition from. E.g. a splash screen will never slide into place it will just appear.
To effect a transition just create a blank form and apply to it a transition out, I would suggest avoiding that strategy though since no device performs such a transition. Devices such as iPhone/Android who perform a transition to show the initial form do that in the native layer which applies to LWUIT applications as well.

Resources