Python strings are immutable sequences with a rich method set for cleaning, searching, splitting, and formatting text — essential for parsing logs, building URLs, and asserting on messages.
Common methods: .strip()/.lstrip()/.rstrip() trim whitespace; .lower()/.upper() normalize case; .split(sep)/.join(iterable) tokenize and assemble; .replace(a, b) substitute; .startswith()/.endswith()/in test membership; .find()/.index() locate; and f-strings (f'{name} has {n} tests') format cleanly. Because strings are immutable, every method returns a NEW string. For validation, combine .strip().lower() to normalize before comparing, and use in for substring assertions on messages.
Normalizing a UI label before asserting: assert 'welcome' in element.text.strip().lower() tolerates surrounding whitespace and case differences that would otherwise cause false failures.
assert error_msg == 'Invalid input' fails even though the UI shows 'Invalid input '. Why, and how do you make it robust?