Skip to content

Commit d4caa10

Browse files
Merge pull request #650 from mozilla/philimon/normalize_regional_phone_fix
Philimon/Normalize_Telephone_Numbers
2 parents e71a14f + 05c3d44 commit d4caa10

File tree

8 files changed

+75
-50
lines changed

8 files changed

+75
-50
lines changed

.github/workflows/l10n.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name: L10N Test Execution
33

44
run-name: ${{ github.actor }} is running l10n tests
55
on:
6-
pull_request:
76
workflow_call:
87
inputs:
98
channel:

ci_l10n_pyproject_headed.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ markers = [
1515
"noxvfb: tests that should not run in xvfb sessions"
1616
]
1717

18-
addopts = "-vs --ci --json-report --json-report-file artifacts/report_headed.json -n auto --reruns 3 --reruns-delay 2 --html=artifacts/report_headed.html"
18+
addopts = "-vs --ci --json-report --json-report-file artifacts/report_headed.json -n auto --reruns 4 --reruns-delay 3 --html=artifacts/report_headed.html"
1919

2020
[tool.ruff]
2121
target-version = "py310"

l10n_CM/Unified/test_demo_ad_0_add_new_address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_verify_new_address_is_added(
5252
def data_sanitizer(util: Utilities, value: str, region: str, state_province: Dict):
5353
value = value.strip()
5454
if value[0] == "+":
55-
return util.normalize_phone_number(value)
55+
return util.normalize_regional_phone_numbers(value, region)
5656
elif len(value) == 2 and value != region:
5757
return state_province.get(value, value)
5858
return value

l10n_CM/region/US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"lowes",
77
"etsy",
88
"calvinklein",
9+
"bestbuy",
910
"demo"
1011
],
1112
"tests": []

modules/page_object_autofill.py

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def update_form_data(
190190
sample_data: AutofillAddressBase | CreditCardBase,
191191
field: str,
192192
value: str | int,
193+
region: str,
193194
):
194195
"""
195196
Update the form field with the new value.
@@ -198,6 +199,7 @@ def update_form_data(
198199
sample_data: sample data instance used to verify change.
199200
field: field being changed.
200201
value: value being added.
202+
region: region being tested.
201203
"""
202204
# updating the profile accordingly
203205
self.update_and_save(field, value)
@@ -206,10 +208,12 @@ def update_form_data(
206208
self.select_autofill_option(field)
207209

208210
# verifying the correct data
209-
self.verify_form_data(sample_data)
211+
self.verify_form_data(sample_data, region)
210212
return self
211213

212-
def verify_form_data(self, sample_data: CreditCardBase | AutofillAddressBase):
214+
def verify_form_data(
215+
self, sample_data: CreditCardBase | AutofillAddressBase, region: str = "US"
216+
):
213217
"""Verify that form is filled correctly against sample data."""
214218
if not self.field_mapping:
215219
# Method is meant to be called by one of the classes that inherit AutoFill (CreditCardFill or AddressFill)
@@ -229,34 +233,55 @@ def verify_form_data(self, sample_data: CreditCardBase | AutofillAddressBase):
229233
if attr_name == "cvv":
230234
continue
231235
expected_value = getattr(sample_data, attr_name, None)
232-
autofilled_field = self.get_element("form-field", labels=[field_name])
233-
if autofilled_field.tag_name.lower() != "select":
234-
autofilled_field_value = autofilled_field.get_attribute("value")
235-
else:
236-
autofilled_field_value = Select(
237-
autofilled_field
238-
).first_selected_option.text
239-
if (
240-
attr_name == "address_level_1"
241-
and autofilled_field_value != expected_value
242-
):
243-
expected_value = self.util.get_state_province_abbreviation(
244-
expected_value
245-
)
246-
elif attr_name == "expiration_date" and len(autofilled_field_value) > 5:
247-
autofilled_field_value = autofilled_field_value.replace("20", "")
248-
249-
elif attr_name == "country":
250-
expected_value = self.util.get_country_local_translation(expected_value)
251-
if attr_name == "expiration_month" and autofilled_field_value.isdigit():
252-
# Handle expiration month comparison - normalize to integers to handle leading zeros
253-
autofilled_field_value = str(int(autofilled_field_value))
254-
expected_value = str(int(expected_value))
255-
256-
assert expected_value in autofilled_field_value, (
257-
f"{autofilled_field_value} is different from {expected_value}"
236+
auto_filled_field_value = self._get_field_value(field_name)
237+
238+
# Normalize values for comparison
239+
expected_value, auto_filled_field_value = self._normalize_values(
240+
attr_name, expected_value, auto_filled_field_value, region
241+
)
242+
243+
assert expected_value in auto_filled_field_value, (
244+
f"Field '{attr_name}' ('{field_name}'): expected '{expected_value}' to be in '{auto_filled_field_value}'"
258245
)
259246

247+
def _get_field_value(self, field_name: str) -> str:
248+
"""Get the value from a form field, handling different element types."""
249+
autofilled_field = self.get_element("form-field", labels=[field_name])
250+
if autofilled_field.tag_name.lower() != "select":
251+
return autofilled_field.get_attribute("value")
252+
else:
253+
return Select(autofilled_field).first_selected_option.text
254+
255+
def _normalize_values(
256+
self,
257+
attr_name: str,
258+
expected_value: str,
259+
auto_filled_field_value: str,
260+
region: str,
261+
) -> tuple[str, str]:
262+
"""Normalize expected and actual values for comparison."""
263+
if attr_name == "address_level_1" and auto_filled_field_value != expected_value:
264+
expected_value = self.util.get_state_province_abbreviation(expected_value)
265+
elif attr_name == "expiration_date" and len(auto_filled_field_value) > 5:
266+
auto_filled_field_value = auto_filled_field_value.replace("20", "")
267+
elif attr_name == "country":
268+
expected_value = self.util.get_country_local_translation(expected_value)
269+
elif attr_name == "telephone":
270+
expected_value = self.util.normalize_regional_phone_numbers(
271+
expected_value, region
272+
)
273+
auto_filled_field_value = self.util.normalize_regional_phone_numbers(
274+
auto_filled_field_value, region
275+
)
276+
277+
# Handle numeric fields
278+
if attr_name == "expiration_month" and auto_filled_field_value.isdigit():
279+
# Handle expiration month comparison - normalize to integers to handle leading zeros
280+
auto_filled_field_value = str(int(auto_filled_field_value))
281+
expected_value = str(int(expected_value))
282+
283+
return expected_value, auto_filled_field_value
284+
260285
def verify_field_autofill_dropdown(
261286
self,
262287
fields_to_test: List[str] = None,
@@ -433,7 +458,7 @@ def verify_all_fields_cleared(self):
433458

434459
@BasePage.context_chrome
435460
def verify_autofill_data_on_hover(
436-
self, autofill_data: CreditCardBase | AutofillAddressBase
461+
self, autofill_data: CreditCardBase | AutofillAddressBase, region: str
437462
):
438463
"""
439464
Verifies that the autofill preview data matches the expected values when hovering
@@ -473,7 +498,7 @@ def verify_autofill_data_on_hover(
473498
)
474499
for field, value in container_data.items():
475500
if field in self.preview_fields:
476-
value = self.sanitize_preview_data(field, str(value))
501+
value = self.sanitize_preview_data(field, str(value), region)
477502
# Check if this value exists in our CreditCardBase | AutofillAddressBase object
478503
is_present = any(
479504
[value in val for val in autofill_data.__dict__.values()]
@@ -482,13 +507,13 @@ def verify_autofill_data_on_hover(
482507
f"Mismatched data: {(field, value)} not in {autofill_data.__dict__.values()}."
483508
)
484509

485-
def sanitize_preview_data(self, field, value):
510+
def sanitize_preview_data(self, field, value, region):
486511
if field == "cc-number":
487512
value = value[-4:]
488513
elif field == "cc-exp-year":
489514
value = value[-2:]
490515
elif field == "tel" or value[0] == "+":
491-
value = self.util.normalize_phone_number(value)
516+
value = self.util.normalize_regional_phone_numbers(value, region)
492517
return value
493518

494519
def select_autofill_option(self, field, index: int = 1):
@@ -576,7 +601,7 @@ def check_autofill_preview_for_field(
576601
self.double_click("form-field", labels=[field])
577602
self.autofill_popup.ensure_autofill_dropdown_visible()
578603
self.autofill_popup.hover("select-form-option")
579-
self.verify_autofill_data_on_hover(sample_data)
604+
self.verify_autofill_data_on_hover(sample_data, region)
580605
self.click_on("form-field", labels=[field])
581606
else:
582607
logging.info(
@@ -636,7 +661,7 @@ def clear_and_verify(
636661

637662
if sample_data:
638663
## verify data
639-
self.verify_form_data(sample_data)
664+
self.verify_form_data(sample_data, region)
640665

641666
# Clear form autofill
642667
self.double_click("form-field", labels=[field])

modules/util.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,9 @@ def generate_localized_phone(self, country_code: str, fake: Faker) -> str:
264264
if phone[:2] != "11":
265265
break
266266
else:
267-
phone = self.normalize_phone_number(fake.phone_number())
267+
phone = self.normalize_regional_phone_numbers(
268+
fake.phone_number(), country_code
269+
)
268270
return phone
269271

270272
def fake_autofill_data(self, country_code) -> AutofillAddressBase:
@@ -517,9 +519,9 @@ def get_state_province_abbreviation(self, full_name: str) -> str:
517519
Returns the abbreviation for a given state, province, or region full name.
518520
519521
:param full_name: The full name of the state, province, or region.
520-
:return: The corresponding abbreviation or "Not Found" if not in the dictionary.
522+
:return: The corresponding abbreviation or the full name itself if not in the dictionary.
521523
"""
522-
return self.state_province_abbr.get(full_name, "Not Found")
524+
return self.state_province_abbr.get(full_name, full_name)
523525

524526
def get_country_local_translation(self, country_name: str) -> str:
525527
"""
@@ -562,16 +564,14 @@ def normalize_regional_phone_numbers(self, phone: str, region: str) -> str:
562564
# Determine country code
563565
country_code = country_codes.get(
564566
region, "1"
565-
) # Default to "1" (US/CA) if region is unknown
567+
) # Default to "1" (US/CA) if the region is unknown
568+
# handle leading zeros
566569
local_number = digits
567570

568-
# Check if phone already contains a valid country code
569-
for code in country_codes.values():
570-
if digits.startswith(code):
571-
country_code = code
572-
# Remove country code from local number
573-
local_number = digits[len(code) :]
574-
break
571+
# Check if the phone number already contains a valid country code
572+
if digits.startswith(country_code):
573+
# Remove country code from the local number
574+
local_number = digits[len(country_code) :]
575575

576576
# Handle leading zero in local numbers (France & Germany)
577577
if region in ["FR", "DE"] and local_number.startswith("0"):

tests/form_autofill/test_updating_address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_update_address(
4444
# Change name field value.
4545
new_name_value = sample_data.name + " Doe"
4646
setattr(sample_data, "name", new_name_value)
47-
address_autofill.update_form_data(sample_data, "name", new_name_value)
47+
address_autofill.update_form_data(sample_data, "name", new_name_value, region)
4848

4949
# Navigate to settings
5050
about_prefs_privacy.open()

tests/form_autofill/test_updating_credit_card.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_update_cc_no_dupe_name(
5757
credit_card_sample_data, field, region
5858
)
5959
credit_card_autofill.update_form_data(
60-
credit_card_sample_data, field, new_field_value
60+
credit_card_sample_data, field, new_field_value, region
6161
)
6262

6363
# navigate to settings

0 commit comments

Comments
 (0)