Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[PWA-586] Country/Region Occasionally Resets initialValue #2456

Merged
merged 9 commits into from
Jun 10, 2020

Conversation

tjwiebell
Copy link
Contributor

@tjwiebell tjwiebell commented Jun 3, 2020

Description

There's an empty cache state for these components where the form they are attached to renders before the backend results for the list of available options in these dropdown components is returned. When that backend response arrives, the components re-render with those options, but the initialValue from the parent context doesn't apply, and the component renders an empty selection. I've more commonly seen this in the Region component, where State will be cleared out after an initial flash of the component.

Once this component has loaded once in the app, it's not reproducible, since the components first render now uses that immediate cached response.

Repro:

  1. Add Simple item to cart and go to /cart
  2. Open Estimate Shipping section and submit an estimate (State = TX)
  3. Open Dev Tools > Local Storage > Delete apollo-cache-persist entry
  4. Refresh the page and open Estimate Shipping section

Expected: State data entered is selected in dropdown
Actual: State is empty

Related Issue

  • [PWA-586] Country/Region Occasionally Resets initialValue

Acceptance

Verification Stakeholders

Specification

Verification Steps

⬆️ Repro steps can be used for verification above ⬆️

Screenshots / Screen Captures (if appropriate)

Checklist

  • I have updated/added tests to cover my changes, if necessary.
  • I have updated the documentation accordingly, if necessary.

@tjwiebell tjwiebell added the version: Patch This changeset includes backwards compatible bug fixes. label Jun 3, 2020
@PWAStudioBot
Copy link
Contributor

PWAStudioBot commented Jun 3, 2020

Messages
📖

Access a deployed version of this PR here. Make sure to wait for the "pwa-pull-request-deploy" job to complete.

📖 DangerCI Failures related to missing labels/description/linked issues/etc will persist until the next push or next nightly build run (assuming they are fixed).
📖

Associated JIRA tickets: PWA-586.

Generated by 🚫 dangerJS against ab0adc9

@devops-pwa-codebuild
Copy link
Collaborator

devops-pwa-codebuild commented Jun 3, 2020

Performance Test Results

The following fails have been reported by WebpageTest. These numbers indicates a possible performance issue with the PR which requires further manual testing to validate.

https://pr-2456.pwa-venia.com : LH Performance Expected 0.85 Actual 0.52, LH Best Practices Expected 1 Actual 0.92
https://pr-2456.pwa-venia.com/venia-tops.html : LH Performance Expected 0.75 Actual 0.36, LH Best Practices Expected 1 Actual 0.92
https://pr-2456.pwa-venia.com/valeria-two-layer-tank.html : LH Performance Expected 0.8 Actual 0.5, LH Accessibility Expected 0.9 Actual 0.89, LH Best Practices Expected 1 Actual 0.92

Copy link
Contributor

@revanth0212 revanth0212 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically speaking loading is the only change right? At first, I thought you removed the initialValue and validate props but they are fed into the same component inside ...inputProps or ...regionProps. Nice.

Would it be possible to add snapshot tests to the country and region components?

@tjwiebell
Copy link
Contributor Author

Technically speaking loading is the only change right? At first, I thought you removed the initialValue and validate props but they are fed into the same component inside ...inputProps or ...regionProps. Nice.

Using loading to disable the field while fetching options + the magical keepState prop that preserves the value between mounts. This might even fix the issue you had in scope of billing address, where you were passing initalValue to the field instead of the form (this bug might have been why you did that).

Would it be possible to add snapshot tests to the country and region components?

Absolutely! Since we do tests in QA, is this code approved to get started on those?

revanth0212
revanth0212 previously approved these changes Jun 4, 2020
Copy link
Contributor

@revanth0212 revanth0212 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Awaiting snapshot tests for Country and Region components.

@tjwiebell
Copy link
Contributor Author

tjwiebell commented Jun 5, 2020

@revanth0212 - Added tests that are a bit coupled to these form input components, but wanted to put out a challenge, maybe you've solved this problem before. I really really tried to mock the Field and Select components in these tests, and could not get it to work. With the following mocks, I was getting an unhelpful PrettyFormatPluginError: val.getMockName is not a function error.

jest.mock('../../Field', () => props => <mock-Field {...props} />);
jest.mock('../../Select', () => 'Select');

I don't know what's different about the Select component, but it seems impossible to mock without getting this error.

@revanth0212
Copy link
Contributor

@revanth0212 - Added tests that are a bit coupled to these form input components, but wanted to put out a challenge, maybe you've solved this problem before. I really really tried to mock the Field and Select components in these tests, and could not get it to work. With the following mocks, I was getting an unhelpful PrettyFormatPluginError: val.getMockName is not a function error.

jest.mock('../../Field', () => props => <mock-Field {...props} />);
jest.mock('../../Select', () => 'Select');

I don't know what's different about the Select component, but it seems impossible to mock without getting this error.

Select is a component but you are returning a string. I guess that is the error. You are returning a component in case of Field though.

revanth0212
revanth0212 previously approved these changes Jun 5, 2020
@dpatil-magento
Copy link
Contributor

QA Pass.

revanth0212
revanth0212 previously approved these changes Jun 9, 2020
Copy link
Contributor

@revanth0212 revanth0212 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding tests @tjwiebell. A couple of comments, you can ignore them if you feel you have addressed those already.

tree.update(<Component {...props} />);
});

expect(mockSetValue).toHaveBeenCalledWith();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
expect(mockSetValue).toHaveBeenCalledWith();
expect(mockSetValue).toHaveBeenCalled();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in ab0adc9.


const { data, error, loading } = useQuery(getRegionsQuery, {
variables: { countryCode: country }
});

let formattedRegionsData = [];
let formattedRegionsData = [{ label: 'Loading Regions...', value: '' }];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test for this? Looks like it is being manipulated in multiple places. A set of tests can be of help.

I see you have added snapshot tests but more verbal ones can be helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in ab0adc9

jimbo
jimbo previously approved these changes Jun 9, 2020
useEffect(() => {
if (country) {
if (hasInitialized.current) {
regionFieldApi.setValue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe indicate this is a reset with a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset() from the fieldApi had the behavior I wanted, so I made that change in ab0adc9, which should be more self documenting. Thanks for pointing out there was much more to that API than the docs lead you to believe.

@dpatil-magento
Copy link
Contributor

Re-verified after changes, looks good.

@dpatil-magento dpatil-magento merged commit 77d97c6 into develop Jun 10, 2020
@dpatil-magento dpatil-magento deleted the tommy/country-region-reset branch June 10, 2020 19:58
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
pkg:peregrine pkg:venia-ui version: Patch This changeset includes backwards compatible bug fixes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants