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

Writing more UI tests (with guidance) #1000

Closed
jywarren opened this issue Apr 8, 2019 · 23 comments
Closed

Writing more UI tests (with guidance) #1000

jywarren opened this issue Apr 8, 2019 · 23 comments

Comments

@jywarren
Copy link
Member

jywarren commented Apr 8, 2019

We need more UI tests to protect and stabilize the UI behaviors of the demo, so that we know when refactors and new features break things. This will build overall stability in the system and let us do more advanced work without chasing bugs. Bugs are natural! No worries! But we can catch them before they get published using more tests.

Our UI tests can be found here: https://github.com/publiclab/image-sequencer/tree/main/test/ui/spec

Instead of testing core functions with unit tests, they set up an HTML environment and simulate someone actually using the buttons and UI.

So in one of these test files, or a new one, we should be able to begin interacting with a full Sequencer UI, by selecting things in the Add Modules select, clicking buttons with $('.btn .uniqueClass').trigger('click'); (or something like that) and then using assertions to test that things really happened, something like this:

    expect($('.step').length).toBe(10); // number of steps shown has changed

This way, we can have more confidence in the UI not breaking. We'd love help with this! I know @harshithpabbati asked a bit about how this might work. Want to try it out?

Once we have one simple test like this, we can use it as a model to add more like it, and get to higher test coverage of our UI code!

@jywarren
Copy link
Member Author

jywarren commented Apr 8, 2019

For example, we should be able to input settings using something like $('.step .step-2 input.brightness').val(24) --

But first, we'll need to add more unique CSS classnames so that we can make calls like that in jQuery. Right now, they're too generic:

<div class="panel-body cal collapse in">
            <div class="row step">
                <div class="col-md-4 details">
                  <h3><span class="load-spin" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></span></h3>
                  <div class="cal collapse in"><p><i>Change the contrast of the image by given value</i></p></div>
                <div class="row" name="contrast">
                    <div class="det cal collapse in">
                           <label for="contrast">contrast for the new image, typically -100 to 100</label>
                           <input class="form-control target" type="range" name="contrast" value="70" placeholder="" min="-100" max="100" step="1">

@vibhorgupta-gh
Copy link

I'd like to take this up. This would be kind of a quest, adding UI tests as we go deeper into implementing more features for IS. Would like to start with some basic tests

@jywarren
Copy link
Member Author

jywarren commented Apr 8, 2019 via email

@vibhorgupta-gh
Copy link

vibhorgupta-gh commented Apr 8, 2019

Nice! I'll get on with improving some tests I already wrote while setting up the UI testing harness.
Rendering of buttons and steps should be a nice starting point.

Also, apologies for shamelessly plugging in my proposal, but trying to make it as comprehensive as possible. What are the chances I'll get reviewed, should I submit one in a couple of hours? It's early morning here, trying to churn it out as fast as I can. Thanks!

@jywarren

@jywarren
Copy link
Member Author

jywarren commented Apr 9, 2019 via email

@harshkhandeparkar
Copy link
Member

Hi. Can someone help with the testing of the $step method? See #833 for reference

@publiclab/is-reviewers @jywarren

@Divy123
Copy link
Member

Divy123 commented Apr 9, 2019

Hi Harsh! I want to work on UI testing and would love to look into!!

@vibhorgupta-gh
Copy link

@jywarren again, apologies for the plug, I sent over the commentable link to my proposal to you on Gitter. My proposal on publiclab.org says I'll be notified via mail once my proposal gets published. It is way too late for reviews, but the link is on Gitter for your reference. Thanks!

@jywarren jywarren added this to the Core improvements milestone May 25, 2019
@rishabhshuklax
Copy link
Member

I would love to work on this issue

@harshkhandeparkar
Copy link
Member

sure go ahead

@Divy123
Copy link
Member

Divy123 commented Aug 30, 2019 via email

@jywarren
Copy link
Member Author

jywarren commented Aug 30, 2019

Much ❤️ to you all!!!

Shall we make a checklist of UI actions that could be tested for?

  • clicking Add Step and confirming a new box appears, and a new image appears -
    test('Resize Module is added', async () => {
    await page.waitForSelector('.step');
    const Length = await page.evaluate(() => document.querySelectorAll('.step').length);
    await page.click('[data-value=\'resize\']');
    const Length1 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length).toBe(1);
    expect(Length1).toBe(2);
    }, timeout);
    test('Brightness Module is added', async () => {
    await page.click('[data-value=\'brightness\']');
    const Length2 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length2).toBe(3);
    }, timeout);
    test('Contrast Module is added', async () => {
    await page.click('[data-value=\'contrast\']');
    const Length3 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length3).toBe(4);
    }, timeout);
    test('Saturation Module is added', async () => {
    await page.click('[data-value=\'saturation\']');
    const Length4 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length4).toBe(5);
    }, timeout);
    test('Rotate Module is added', async () => {
    await page.click('[data-value=\'rotate\']');
    const Length5 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length5).toBe(6);
    }, timeout);
    test('Crop Module is added', async () => {
    await page.click('[data-value=\'crop\']');
    const Length6 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length6).toBe(7);
    }, timeout);
  • Add Step for various modules -
    test('Resize Module is added', async () => {
    await page.waitForSelector('.step');
    const Length = await page.evaluate(() => document.querySelectorAll('.step').length);
    await page.click('[data-value=\'resize\']');
    const Length1 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length).toBe(1);
    expect(Length1).toBe(2);
    }, timeout);
    test('Brightness Module is added', async () => {
    await page.click('[data-value=\'brightness\']');
    const Length2 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length2).toBe(3);
    }, timeout);
    test('Contrast Module is added', async () => {
    await page.click('[data-value=\'contrast\']');
    const Length3 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length3).toBe(4);
    }, timeout);
    test('Saturation Module is added', async () => {
    await page.click('[data-value=\'saturation\']');
    const Length4 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length4).toBe(5);
    }, timeout);
    test('Rotate Module is added', async () => {
    await page.click('[data-value=\'rotate\']');
    const Length5 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length5).toBe(6);
    }, timeout);
    test('Crop Module is added', async () => {
    await page.click('[data-value=\'crop\']');
    const Length6 = await page.evaluate(() => document.querySelectorAll('.step').length);
    expect(Length6).toBe(7);
    }, timeout);
  • Clicking Delete Step removes the image https://github.com/publiclab/image-sequencer/blob/main/test/ui-2/test/clear_and_delete_step.test.js#L58
  • Clicking Insert Step adds a new box, and modifies the image

These could be largely independent from the UI implementation as long as the add step, delete step, insert step elements have standard classnames!

(update: checked boxes above)

@jywarren
Copy link
Member Author

Also updated location of existing UI tests! https://github.com/publiclab/image-sequencer/tree/main/test/ui/spec

@jywarren
Copy link
Member Author

Here is the most likely section for the listed tests above!

it('select step ui', function() {
expect(defaultHtmlSequencerUi.selectNewStepUi).toHaveBeenCalled();
});
it('add step ui', function() {
expect(defaultHtmlSequencerUi.addStepUi).toHaveBeenCalled();
});
it('remove step ui', function() {
expect(defaultHtmlSequencerUi.removeStepUi).toHaveBeenCalled();
});
it('import options from url', function() {
expect(defaultHtmlSequencerUi.importStepsFromUrlHash).toHaveBeenCalled();
});

Note that we are not yet testing click events and such. I think the tests are just really minimal stubs, confirming that the UI was set up, but not testing that it works, is that right?

Also:

@Divy123
Copy link
Member

Divy123 commented Sep 1, 2019

As I discussed with Pranshu, he suggested that testing with Jest along with puppeteer is a good way to proceed here.
What do you think @jywarren , @blurry-x-face ?

@jywarren
Copy link
Member Author

jywarren commented Sep 1, 2019

Hi! I'm not against a weighing of pros/cons to switching test libraries, but is there a problem with the current test setup that you're interested in addressing by switching?

jywarren added a commit that referenced this issue Sep 1, 2019
@jywarren
Copy link
Member Author

jywarren commented Sep 1, 2019

Gaah! I accidentally committed to main branch here, i'm sorry:

fb452f7

However, you can see a very clear UI test that is only 3 lines, for the quick selector! cc @harshithpabbati @Divy123 @rexagod @blurry-x-face

@jywarren
Copy link
Member Author

jywarren commented Sep 1, 2019

I apologize for the mistake, i'll revert it as soon as it fails, but will open it in a new PR.

@jywarren
Copy link
Member Author

jywarren commented Sep 1, 2019

Reverted, now working on it at: #1242

To address #1238, which Harsh identified, it would be something like:

  it('allows changing brightness value using input and Apply button', function() {
    $("[data-value='brightness']").click();
    var brightnessImage1 = $('.step:last img')[0].src;
    $('.step:last input.form-control').val('25%'); // change the value
    $('.step:last .btn-save').click(); // apply the change
    var brightnessImage2 = $('.step:last img')[0].src;
    expect(brightnessImage1).not.toEqual(brightnessImage2);
  });

@jywarren
Copy link
Member Author

jywarren commented Sep 1, 2019

Does this makes sense to you all? cc @publiclab/is-reviewers Thanks!

@rishabhshuklax
Copy link
Member

Hi! I'm not against a weighing of pros/cons to switching test libraries, but is there a problem with the current test setup that you're interested in addressing by switching?

Actually jest is a more maintained testing library but I will look through jasmine.

Thanks @jywarren
cc: @Divy123

@vaibhavmatta
Copy link

@jywarren I am claiming it now. Let us work on it together.! The UI needs to be stable. Will make a PR for this super soon.
Thanks

jywarren added a commit that referenced this issue Dec 16, 2019
@jywarren
Copy link
Member Author

Closing this in favor of #1369 now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants