-
Notifications
You must be signed in to change notification settings - Fork 16
[Java] visual implemented with subclass #259
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
Conversation
2bf1c4c
to
70ab000
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also prefer this over 256. It's more intuitive and not as annoying to have to do .visual()
for all visual commands.
driver.get("https://www.saucedemo.com/"); | ||
|
||
// 6. Use the session to take a snapshot | ||
session.takeSnapshot("Sauce Demo Page"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@titusfortner I also prefer this approach over PR 256
.build(); | ||
|
||
// 3. Start the Session with SauceOptions | ||
VisualSession session = new VisualSession(sauceOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we considered enforcing the 3 mandatory parameters through the constructor instead of runtime exceptions?
VisualSession session = new VisualSession(sauceOptions, "My Test Name", "My Project Name");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't care about project name. "Build Name" is probably what they want, and if they want something different, setProjectName()
should be sufficient.
Test Name / init value is a little harder because we can't provide a reasonable default.
I did try some implementations that put it in the constructor, but we probably need to be encouraging people to set this regardless: sauceOptions.setName(testName.getMethodName())
Maybe we update examples for TestRunner instead of just language so this always gets shown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@titusfortner I think projectName
is mandatory. Hence, I'm suggesting to make it as part of a constructor.
How does .setName("My Test Name")
propogate to visual? In visual there's no concept of test name, rather a snapshotName
.
Agreed about init()
Can you elaborate on why you want to encourage people to sauceOptions.setName(testName.getMethodName())
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only need to avoid the default Regardless, that can be up to the end user to manage if the default doesn't work for them, but that also needs to be set in projectName
in a Code Parameterized paradigm, not in a Build Differentiated paradigm, and I generally don't think that parameterization is the best solution for configuration variations.VisualOptions
class, not the VisualSession
class.
setName()
is for init()
not for takeSnapshot()
.
I could be convinced to require SauceOptions#setName(Name)
in all Sauce tests, not just visual ones. I wish JUnit made it easier to get the method name by default (I'm spoiled in Ruby because RSpec makes it globally accessible from a class variable). Anyway, we should have that discussion prior to Sauce Bindings v2.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only need to avoid the default projectName in a Code Parameterized paradigm, not in a Build Differentiated paradigm
Actually looking at your code below this isn't true either.
Instead of "Project Name"
it would be "Sauce Bindings"
(pulled from the property that is getting set the line before; which is only necessary when running locally, since running it on a CI will use whatever the Build name of the CI is). Actually, we probably should discuss which takes precedence separately.
What about something like this @titusfortner ? @RunWith(Parameterized.class)
public class RealWorldVisualTest {
private VisualSession session;
@Before
public void setup() {
System.setProperty("BUILD_NAME", "Sauce Bindings");
//Project name is mandatory
VisualOptions visualOptions = new VisualOptions("Project Name");
//Visual doesn't support everything that Sauce does
// so it's disadvantageous to configure browser, version, os through SauceOptions
visualOptions.setBrowserName(browserName);
visualOptions.setBrowserVersion(browserVersion);
visualOptions.setPlatform(platform);
SauceOptions sauceOptions = new SauceOptions(visualOptions);
VisualSession session = new VisualSession(sauceOptions);
session.start();
}
@After
public void cleanUp() {
if (session != null) {
//TODO visual.end needs to be called here
session.stop(true);
}
}
@Parameterized.Parameter
public String browserName;
@Parameterized.Parameter(2)
public String browserVersion;
@Parameterized.Parameter(1)
public String platform;
@Parameterized.Parameter(3)
public String viewportSize;
@Parameterized.Parameter(4)
public String deviceName;
@Parameterized.Parameters(name = "{4}")
public static Collection<Object[]> crossBrowserData() {
return Arrays.asList(new Object[][]{
{"Chrome", "Windows 10", "latest", "412x732", "Pixel XL"},
{"Chrome", "Windows 10", "latest", "412x869", "Galaxy Note 10+"},
{"Safari", "macOS 10.15", "latest", "375x812", "iPhone X"}
});
}
@Test
public void checksOnePage() {
// open the page
session.init(deviceName);
session.takeSnapshot("Page Name");
session.stop(); //I don't know if this need to be called first to get back an object of results
assertNull(session.hasVisualDifferences());
}
}
|
Edit: see code example below, it might explain things better.
What makes you say this? Visual tests are run on Sauce, and everything you can do on Sauce you can do with screener.io as a go between. I guess how we think of it depends on whether we're running Visual Tests as an add-on to existing functional tests or in a separate suite just for visual tests. I kind of like the idea of advocating for them to be separate, but we don't need to force that. I'm actually wondering what it might look like to show off 2 test suites:
I don't think we should have a String in a constructor for something that can have a reasonable default (
Hmm, we could store the results in the session rather than requiring a user to get it, but I'm not sure that makes sense since you lose access to visual after
I guess we could put it in the test watcher like this if we are mixing functional & visual:
|
70ab000
to
4756ec7
Compare
Added What gets printed at the end of a passing test:
Failing test:
|
Your example would look like this:
|
4756ec7
to
3584d88
Compare
Ok, just added resolution / viewport size enums... Parameterized values don't have to be Strings, right?
We could do this?
Which would let us do this:
|
e2728d4
to
5a747a8
Compare
…r is specified, set the time value to persist across execution as a System property to more accurately represent a build.
29cf5c9
to
67d4ccd
Compare
@titusfortner this is certainly a cleaner approach. I'm finding a few small things that are throwing me off:
|
Technically it's the static methods (e.g., I'd love to be able to have We could do this: SauceOptions.chrome().setPlatformName(x).setVisualOptions().setVisualSomething(y).build().setBrowserVersion(z).build() But having 2 |
subsumed by #276 |
This is an alternative to #256
This is more in line with the API @nadvolod created in #182
I think I prefer this one?
You still have to
setName()
in Options, andVisualSession
only has a constructor that takes aSauceOptions
instance, but since we are specifyingVisualSession
, we no longer need to usesetVisual()
in Options to indicate that it is a visual test. Also, no need to toggle on Data Center; the URL can be hard coded inVisualSession
.setVisualOptions(VisualOptions)
remains the same as in [Java] Add support for visual tests #256visual()
method insession
: