Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Code cleanup #39

Merged
merged 2 commits into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion issues/1/commit_id.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
da2e6688c3f16e8db76d2bcf4b098be5990e8968
bde67d0e2a370e7470e59b038a8ff920ec4fab6c
Binary file modified issues/1/flow.mitm
Binary file not shown.
8 changes: 4 additions & 4 deletions issues/1/issue_data.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"price": 8000.0,
"title": "[Paid] [$8000] zip /postcode validation error message not displayed for entering `,` on the Home address screen",
"issue_repo_steps": "Action performed: 1. go to Settings > profile> personal details >Home address\r\n2. type the zip /postcode as ,\n\nExpected result: it should show validation error message\n\nActual result: None",
"_issue_id": "14958"
"price": 250.0,
"title": "[HOLD for payment 2025-02-06] [$250] Expense - Hold option is missing in the context menu",
"issue_repo_steps": "If you haven\u2019t already, check out our [contributing guidelines](https://github.com/Expensify/ReactNativeChat/blob/main/contributingGuides/CONTRIBUTING.md) for onboarding and email [email protected] to request to join our Slack channel!\n___\n\n**Version Number:** 9.0.90-0\n**Reproducible in staging?:** Yes\n**Reproducible in production?:** No\n**If this was caught on HybridApp, is this reproducible on New Expensify Standalone?:** N/A\n**If this was caught during regression testing, add the test name, ID and link from TestRail:** Exp\n**Email or phone of affected tester (no customers):** [email protected]\n**Issue reported by:** Applause Internal Team\n**Device used:** Mac 15.0 / Chrome\n**App Component:** Money Requests\n\n## Action Performed:\n1. Go to staging.new.expensify.com\n2. Go to workspace chat.\n3. Submit two expenses to the workspace chat.\n4. Go to expense report.\n5. Click on the expense preview.\n6. Go back to the expense report.\n7. Right click on the expense preview.\n\n## Expected Result:\nThere should be Hold option in the context menu (production behavior).\n\n## Actual Result:\nHold option is missing in the context menu.\n\n## Workaround:\nUnknown\n\n## Platforms:\n- [x] Android: Standalone\n- [x] Android: HybridApp\n- [x] Android: mWeb Chrome\n- [x] iOS: Standalone\n- [x] iOS: HybridApp\n- [x] iOS: mWeb Safari\n- [x] MacOS: Chrome / Safari\n- [x] MacOS: Desktop\n\n## Screenshots/Videos\n\nhttps://github.com/user-attachments/assets/b821e159-ea71-4d2d-836c-ebd605fb42c0\n\n[View all open jobs on GitHub](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22)\n<details><summary>Upwork Automation - Do Not Edit</summary>\n <ul>\n <li>Upwork Job URL: https://www.upwork.com/jobs/~021884172494858147022</li>\n <li>Upwork Job ID: 1884172494858147022</li>\n <li>Last Price Increase: 2025-01-28</li>\n </ul>\n</details>\n\n<details><summary>Issue Owner</summary>Current Issue Owner: @</details>\n\n<details><summary>Issue Owner</summary>Current Issue Owner: @mallenexpensify</details>",
"_issue_id": "55827"
}
22 changes: 0 additions & 22 deletions issues/1/issue_introduction.patch
Original file line number Diff line number Diff line change
@@ -1,22 +0,0 @@
diff --git a/src/CONST.ts b/src/CONST.ts
index 8e38812ccdc..2628d574257 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -3615,7 +3615,7 @@ const CONST = {
},
GA: {},
GB: {
- regex: /^[A-Z]{1,2}[0-9R][0-9A-Z]?\s*[0-9][A-Z-CIKMOV]{2}$/,
+ regex: /^(,|[A-Z]{1,2}[0-9R][0-9A-Z]?\s*([0-9][ABD-HJLNP-UW-Z]{2})?)$/,
samples: 'LA102UX, BL2F8FX, BD1S9LU, WR4G 6LH',
},
GD: {},
@@ -4134,7 +4134,7 @@ const CONST = {
UG: {},
UM: {},
US: {
- regex: /^[0-9]{5}(?:[- ][0-9]{4})?$/,
+ regex: /^(,|[A-Za-z0-9]{5,10})$/,
samples: '12345, 12345-1234, 12345 1234',
},
UY: {
1 change: 1 addition & 0 deletions issues/1/revert_command.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
git reset --hard 75bf54eb0166d846af9836bd6e95787b143bc15e
286 changes: 165 additions & 121 deletions issues/1/test.py
Original file line number Diff line number Diff line change
@@ -1,134 +1,178 @@
import sys, os

base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.insert(0, base_path)

from playwright.sync_api import sync_playwright, expect
import re, time
import imaplib
import email
import random
import string

NEWDOT_URL = "https://dev.new.expensify.com:8082/"
EMAIL = "[email protected]"
PASSWORD = "vjycqezohxxrdhzr"


def new_dot_login(page, email):
page.goto(NEWDOT_URL)
page.locator('input[type="email"]').fill(email)
page.wait_for_timeout(2000)
page.get_by_role("button", name="Continue").nth(0).click()
page.wait_for_timeout(10000)
page.locator('input[data-testid="validateCode"]').fill("123456")


def zip_error(page, assertion_errors):

try:
page.get_by_label("My settings").click()
page.wait_for_timeout(1000)
page.get_by_label("England's Lane, London,").click()
page.wait_for_timeout(1000)
page.get_by_label("Address line 1").get_by_role("textbox").fill("Maliebaan 87")
page.wait_for_timeout(1000)
page.get_by_text("Maliebaan").first.click()
page.wait_for_timeout(1000)
page.get_by_role("textbox", name="Zip / Postcode").fill("1012 JS")
page.wait_for_timeout(1000)
page.get_by_role("button", name="Save").click()
page.wait_for_timeout(1000)
expect(page.get_by_text("Incorrect zip code format.")).not_to_be_visible()
except AssertionError as e:
assertion_errors.append(f"Error: Zip code validation failed for 'Maliebaan 87': {str(e)}")

try:
page.get_by_label("87 Maliebaan, Utrecht,").click()
page.wait_for_timeout(1000)
page.get_by_label("Address line 1").get_by_role("textbox").fill("tokyo")
page.wait_for_timeout(1000)
page.get_by_text("Tokyo Metro Marunouchi Line").click()
page.wait_for_timeout(1000)
page.get_by_role("textbox", name="Zip / Postcode").fill("100-0001")
page.wait_for_timeout(1000)
page.get_by_role("button", name="Save").click()
page.wait_for_timeout(1000)
expect(page.get_by_text("Incorrect zip code format.")).not_to_be_visible()
except AssertionError as e:
assertion_errors.append(f"Error: Zip code validation failed for 'Tokyo Metro Marunouchi Line': {str(e)}")

try:
page.get_by_label("Tokyo Metro Marunouchi Line,").click()
page.wait_for_timeout(1000)
page.get_by_label("Address line 1").get_by_role("textbox").fill("engla")
page.wait_for_timeout(1000)
page.get_by_text("England's Lane").click()
page.wait_for_timeout(1000)
page.get_by_role("textbox", name="Zip / Postcode").fill("SW1A 1AA")
page.wait_for_timeout(1000)
page.get_by_role("button", name="Save").click()
page.wait_for_timeout(1000)
expect(page.get_by_text("Incorrect zip code format.")).not_to_be_visible()
except AssertionError as e:
assertion_errors.append(f"Error: Zip code validation failed for 'SW1A 1AA': {str(e)}")

try:
page.get_by_label("England's Lane, London,").click()
page.get_by_role("textbox", name="Zip / Postcode").fill(",")
page.wait_for_timeout(1000)
page.get_by_role("button", name="Save").click()
page.wait_for_timeout(1000)
expect(page.get_by_text("Incorrect zip code format.")).to_be_visible()
except AssertionError as e:
assertion_errors.append(f"Error: Zip code validation failed for ',': {str(e)}")

try:
page.get_by_label("Back").click()
page.get_by_label("England's Lane, London,").click()
page.wait_for_timeout(1000)
page.get_by_label("Address line 1").get_by_role("textbox").click()
page.get_by_label("Address line 1").get_by_role("textbox").fill("2574 Fairfield Road")
page.wait_for_timeout(1000)
page.get_by_text("Fairfield Road").first.click()
page.wait_for_timeout(1000)
page.get_by_role("textbox", name="Zip / Postcode").fill("234GEs")
page.wait_for_timeout(1000)
page.get_by_role("button", name="Save").click()
page.wait_for_timeout(1000)
expect(page.get_by_text("Incorrect zip code format.")).to_be_visible()
except AssertionError as e:
assertion_errors.append(f"Error: Zip code validation failed for 'England's Lane, London': {str(e)}")


def test_expensify_0000():
assertion_errors = [] # List to store assertion errors
import re
from email.header import decode_header
from playwright.sync_api import sync_playwright, expect

with sync_playwright() as p:
browser = p.chromium.launch(proxy = {"server": "http://localhost:8080"}, headless = False, args = ["--no-sandbox", "--disable-dev-shm-usage", "--ignore-certificate-errors", "--disable-web-security", "--disable-features=IsolateOrigins,site-per-process"], slow_mo = None, channel = "chromium")
first_user_context = browser.new_context(ignore_https_errors=True)
page = first_user_context.new_page()
page.wait_for_timeout(2000)
# Enter Gmail credentials for a disposable
GMAIL_NAME = "nomandevtur+55827.2"
GMAIL_APP_PASSWORD = "tpye xlsj axyq nltq"


new_dot_login(page, "[email protected]")
def get_test_user_info(seed = None, first_name = None, last_name = None):
if first_name is None:
first_name = GMAIL_NAME

if last_name is None:
last_name = ""

zip_error(page, assertion_errors)
email = f"{GMAIL_NAME}+{seed}@gmail.com" if seed is not None else f"{GMAIL_NAME}@gmail.com"

return {"email": email, "password": GMAIL_APP_PASSWORD, "first_name": first_name, "last_name": last_name}

browser.close()
def delete_email_inbox(user_email, password, retries=5, delay=10):
imap = imaplib.IMAP4_SSL("imap.gmail.com")
imap.login(user_email, password)


if assertion_errors:
print("\nAssertion Errors:")
for error in assertion_errors:
print(f"- {error}")
raise AssertionError("One or more assertions failed. Check the logs above.")
# Select inbox and delete all emails
imap.select("inbox")
status, all_emails = imap.search(None, "ALL")
if status == "OK":
for email_id in all_emails[0].split():
imap.store(email_id, "+FLAGS", "\\Deleted")
imap.expunge()


def get_magic_code(user_email, password, retries=5, delay=5):
# Connect to the server
imap = imaplib.IMAP4_SSL("imap.gmail.com")
imap.login(user_email, password)

for _ in range(retries):
imap.select("inbox")
status, messages = imap.search(None, '(UNSEEN SUBJECT "Expensify magic sign-in code:")')

if status == "OK":
email_ids = messages[0].split()
print(email_ids)

if email_ids:
latest_email_id = email_ids[-1]
status, msg_data = imap.fetch(latest_email_id, "(RFC822)")

for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or "utf-8")

# Search for the magic code in the subject
match = re.search(r"Expensify magic sign-in code: (\d+)", subject)
if match:
code = match.group(1)
imap.logout()
return code
else:
print("No unread emails found with the subject. Retrying...")
else:
print("Failed to retrieve emails. Retrying...")



imap.logout()
print("Max retries reached. Email not found.")
return None


def select_activity(page, first_name, last_name, activity_text):
expect(page.get_by_text("What do you want to do today?")).to_be_visible()

# Select activity in onboarding page and click Continue
page.get_by_label(activity_text).click()

# Enter first name, last name and click continue
page.get_by_role("textbox", name="First name").fill(first_name)
page.get_by_role("textbox", name="Last name").fill(last_name)
page.get_by_role("button", name="Continue").last.click()


def login_user(page, user_info, activity_text="Track and budget expenses"):
# Clear cookies, local storage, and session storage
page.context.clear_cookies()

page.goto('https://dev.new.expensify.com:8082/')
page.wait_for_load_state('load')

page.get_by_test_id("username").fill(user_info["email"])
page.get_by_role("button", name="Continue").click()

join_button = page.get_by_role("button", name="Join")
validate_code_input = page.locator('input[data-testid="validateCode"]')
expect(join_button.or_(validate_code_input)).to_be_visible()

page.wait_for_timeout(5000)
if (join_button.is_visible()):
join_button.click(timeout=3000)
else:
# magic_code = get_magic_code(user_info["email"], user_info["password"], retries=6, delay=5)

# if magic_code is None:
# #Retrying again
# page.locator(f"span:has-text('Didn't receive a magic code?')").first.click()
# magic_code = get_magic_code(user_info["email"], user_info["password"], retries=6, delay=5)
magic_code = "123456"
print(f"Magic code: {magic_code}")
validate_code_input.fill(magic_code)

page.wait_for_timeout(3000)

select_activity_dialog = page.get_by_text("What do you want to do today?")
if select_activity_dialog.count() > 0:
select_activity(page, user_info["first_name"], user_info["last_name"], activity_text)


def launch_app(pw, headless=False, device=None, geolocation=None):
browser = pw.chromium.launch(headless = headless,
proxy = {"server": "http://127.0.0.1:8080/"}, slow_mo = 1000,
args=[
"--ignore-certificate-errors",
"--disable-web-security",
"--disable-features=IsolateOrigins,site-per-process"
]
)

context_args = {"viewport": {"width": 1024, "height": 640}}
if device:
context_args.update(pw.devices[device])
if geolocation:
context_args["geolocation"] = geolocation
context_args["permissions"] = ["geolocation"]
context = browser.new_context(**context_args)
page = context.new_page()
return browser, context, page


def test_55827():
with sync_playwright() as p:

user_info = get_test_user_info()

if __name__ == "__main__":
try:
test_expensify_0000()
except AssertionError as e:
print(str(e))
delete_email_inbox(user_info["email"], user_info["password"], retries=6, delay=5)

browser, context, page = launch_app(p)
login_user(page, user_info)

page.wait_for_timeout(3000)

page.get_by_test_id("3813452933783910").click()
page.wait_for_timeout(3000)
page.get_by_label("View details").click()
page.wait_for_timeout(3000)
page.locator("div:has-text('$20.00')").last.click()
page.wait_for_timeout(3000)
page.get_by_label("$20.00 for asd").last.click()
page.wait_for_timeout(3000)
page.get_by_label("Back").click()
page.wait_for_timeout(3000)
page.get_by_label("From Expense Report #").click()
page.wait_for_timeout(3000)
page.locator("div:has-text('$20.00')").last.click(button="right")
page.wait_for_timeout(3000)

text_locator = page.get_by_text("Hold")
expect(text_locator).to_be_visible()

page.close()
browser.close()
Loading