How does one check the state of a menu item in an XCUI test - swift

Here is my use case...
My application has a number of menu items that have their state toggled between on and off based on a boolean that is also tied to a user default. That is, when the user clicks the menu item it not only toggles the state, it also saves that in the user defaults.
This is all working well but I'm trying to add tests to my XCUIApplication tests to check that the state is indeed saved from one application run to another. However I am unable to determine how to actually test the state of the menu item.
I find the menu item and confirm that it exists, has the correct title, and is enabled, as seen here:
let item = app.menuItems["viewHighlightChanges"]
XCTAssertTrue(item.exists)
XCTAssertEqual(item.title, "Highlight Changes")
XCTAssertTrue(item.isEnabled)
I can then toggle the item by clicking it:
item.click()
And I can confirm visually that this is all working.
But what I cannot figure out is how to determine if the menu item is check (state is on) or not checked (state is off). I had thought that it may be encoded in item.value but that is returning nil both before and after the click. I also thought it may be in item.isSelected but selected is not the same as state and in this case is always false both before and after the click.
My goal is to record the state after clicking, then exit and restart the app, and test the state again to see that it properly retained itself. I know that it is working because I can verify the state visually as the test runs, but the whole purpose of an automated test is that the computer should tell me if it worked.
Any ideas?

Related

Cubit logout function (User state -> NoUser state) causes "watchers" of that User state to cause errors in the moment before logout actually occurs

~simplified example for brevity~
I have 2 Cubit states in my app: User and NoUser. The User state (object) holds a bunch of local preferences that are loaded when the app is initially opened (theming, color, text-size, accessibility preferences, etc.).
My settings page has a bunch of watchers that check to see which preference is selected. For example, for text-size preferences, I have 3 checkmarks (small, regular, large), each are shown as selected or not on the screen based on code like this:
CheckMark(
title: "Small text selected",
isChecked: context.watch<UserCubit>().stateAsUser.textSizeEnum == TextSizeEnum.small,
),
stateAsUser just unconditionally returns the UserState (from the UserCubit), as User (type cast). This is what is causing the problem.
When I logout of the app, I call a UserCubit method that basically switches the state from User to NoUser, then a BlocListener inside my splash screen navigates to the logged out screen after seeing the state go from User to NoUser.
Steps that cause the problem:
State is User.
User presses logout, and UserCubit.logout() is called, which basically just emits NoUser.
The settings that watch this state suddenly are casting a NoUser type to User inside the stateAsUser method for a split-second, causing exceptions to be thrown, before the app is navigated to the logged out screen.
I'd prefer not having to check if the state is truly User for these settings, because then I'd have to still supply a "default value" to be displayed to these setting checkers in the split-second after a NoUser is emitted, and before the navigation occurs.
I sort of just want to "ignore", or "stay with whatever value was there before state became NoUser" for the split second before the user is pushed to another screen and the watchers become inactive.
I just don't know how to fix this. Any input would be great, thanks!

Powerapps - Unable to change Toggle on separate screen

I'm trying to use toggles on an inactive screen as a replacement for functions (and thus help code reuse), however I'm stuck as my toggle won't activate unless I visit the page it's on. I found plenty of working examples online but somehow can't get it to work for me.
Overview:
I have a button on screen1 and a toggle on screen2.
During my button's OnSelect event, a variable varSendData is being set to true like so:
Set (varSendData, true)
The toggle has its Default property set to varSendData.
The OnCheck property of the toggle contains the code to be executed:
Notify("This works")
Problem:
While the variable varSendData is correctly being set to true, nothing happens while I'm on the screen1 with the button. Only when I visit the screen2 with the toggle (even if in edit mode only) does the toggle change state and execute the code in the OnCheck property. I tried using the OnChange property of the toggle, however that has the same effect/limitation.
Furthermore, if I set the variable (varSendData) back to false before visiting screen2 then nothing happens from which I conclude that the toggle is only triggered (changed) if the page it's on is visible/active.
Any ideas on how I could get the toggle to change state even if I'm not screen2? Or any other ideas on how I could reuse the same code from different screens?
It's a limitation of the method the actual code is calling. In order to allow the HTML to refresh from this "Notify("This Works"). You would need to also have a function that refreshes the HTML in the screen your currently viewing.
I was able to get this to work by adding a label and setting its text property to be If(Toggle6.Value = true, "yes", "no").
Literally adding this in allowed the notification to pop up. Nothing extra.

Testing keyboard input for blueprint select with react testing library

I have created a codesandbox to illustrate my issue here:
https://codesandbox.io/s/floral-resonance-z2h43?file=/src/SelectExample.spec.tsx
I am trying to test the keyboard navigation within a blueprint select. That is opening the select by clicking the button, then pressing key arrows untill the desired item is active and confirming with enter which closes the select.
The functionality works perfectly fine.
I however fail to get the unit test(s) to work. As you can see in the linked sandbox a unit test that select the new item via mouseclick works.
I however have run out of ideas how to trigger the onChange of the SelectExample with keyboard inputs.
userEvent.keyboard() doesn't work and fireEvent doesn't either (though I'm not sure what to target considering how blueprint implements the select and that I can only add data-testid to some elements, but going to any number of parentElements from the items which have testids didn't work either). Same issue with userevent.type(), unless the target for that is the desired item in which case the test pases but only because the implementation type() clicks on it before entering its text.
References for the keyboard input:
https://testing-library.com/docs/dom-testing-library/api-events/
https://testing-library.com/docs/ecosystem-user-event/
I'd appreciate any input.

How to create a 'non-binding' binding in MVVM?

My question is very close to this one:
How can I switch tabs programatically from within my ViewModel?
But what I want to do is just switch tabs as a courtesy to the user, and not make it binding. (When the user starts a 'scan', I would like to switch to the 'monitoring' tab, but not prevent him changing tabs just because the scan is still running).
I've worked out that setting mode=OneWay will avoid the user stopping the scan by changing tabs, but my original idea of binding to 'Scanning' doesn't work great because when that gets set to 'false', the tab goes to 'not selected' and I just get a blank rectangle. I could only invoke the 'property changed' when it goes from false to true, but that seems very wrong.
I ended up deciding that code behind was the best way to go. It's a UI convenience for the user and the ViewModel doesn't need to know anything about it. So I hook into the 'Start' button and switch tabs when it's clicked.

How do you get the Eclipse menubar to update on demand?

I'm working on a plugin aiming to hide a swathe of menu contributions, then slowly reintroduce them to the UI according to how confident/experienced the user is, with help and introductory information given to the user at each step. So far I can happily hide menu contributions using activities. Getting them back has proved to be slightly more difficult, however.
I have menu contributions being hidden and shown via activities, but the problem I've run in to is that the menu isn't instantly updating to reflect the activites. When my provided variable is changed, the activities are being started/stopped appropriately, but the menu doesn't immediately change. That is, until you change view or perspective- actions which cause the menu to be refreshed.
I've tried calling refresh() on the MenuManager, as per this question, to no avail.
Obviously my expression is being evaluated immediately, but how can I get the menu itself to update/refresh immediately?
Thanks!
It turns out there were issues with fireSourceChanged().
Calling: fireSourceChanged(int sourcePriority, Map sourceValuesByName) doesn't work for me.
But calling fireSourceChanged(int sourcePriority, String sourceName, Object sourceValue) does work.
I really don't know why that is - could be an Eclipse bug??